如何在angular 6库中添加外部js文件

时间:2018-06-29 08:22:38

标签: angular angular-cli angular6

我正在使用angular 6创建一个基于角度材料的角度库,为此我需要包含Hammer js库。

我知道在angular 6中,我们可以在项目配置下的angular.json中添加外部js库。但这在库的情况下不起作用。我试图通过以下方式添加外部库。

"my-library": {
  "root": "projects/my-library",
  "sourceRoot": "projects/my-library/src",
  "projectType": "library",
  "architect": {
    "build": {
      "builder": "@angular-devkit/build-ng-packagr:build",
      "options": {
        "tsConfig": "projects/my-library/tsconfig.lib.json",
        "project": "projects/my-library/ng-package.json",
        "scripts": [
          "../node_modules/hammerjs/hammer.min.js"
        ]
      }
    }
}

但是我遇到了这个错误。

  

架构验证失败,出现以下错误:     数据路径“”不应具有其他属性(脚本)。

请提出在角度库中添加外部js文件的正确方法。

9 个答案:

答案 0 :(得分:1)

您可以在 tsconfig.lib.jso n文件中添加外部库。

打开该文件,然后在 compilerOptios 中找到的 types 节点下添加您的欲望库。我举个例子。就我而言,我从项目节点模块中引用了该库。您可以使用Hammer.js库执行相同的操作。祝你好运

using types to configure external js file

答案 1 :(得分:0)

在节点模块的路径之前删除../

"scripts": [
    "node_modules/hammerjs/hammer.min.js"
]

答案 2 :(得分:0)

如果以前使用过角版本1.x,则应尝试使用以下命令。它对我有用。

ng update @angular/cli --migrate-only --from=1.7.4

答案 3 :(得分:0)

首先将库添加到index.html或

"scripts": [
"node_modules/hammerjs/hammer.min.js"
]
  

npm install d3-保存

     

npm install @ types / d3 --save-dev

如果该库的@ types /中没有可用的类型,您仍然可以通过手动为其添加类型来使用它:

  1. 首先,在src /文件夹中创建一个Types.d.ts文件。此文件将自动包含为全局类型定义。
  2. 然后在src / typings.d.ts中添加以下代码:

    声明模块'typeless-package';

  3. 最后,在使用该库的组件或文件中,添加以下代码:

    从'typeless-package'中导入*作为typelessPackage;

    typelessPackage.method();

请遵循link

答案 4 :(得分:0)

这是我们需要解决的两个可能的问题

1)如何在主角度项目(演示项目)中添加外部JS的引用

2)如何在NPM软件包中添加外部JS的引用。

第一种情况的解决方案是:

在script标签中的主要angular项目的angular.json文件中提供外部JS的引用,并像这样从库的node_modules文件夹中提供包的路径。

"scripts": [ "./projects/my-cool-library/node_modules/my-exteranl-library/dist/x.js"]

第二种情况的解决方案是:

方法1

因此,现在您已经从库中创建了NPM软件包,并将在其他项目中使用它。显然,一旦您下载软件包,您的第三方软件包依赖项将自动下载,您只需在新项目的angular.json文件的脚本标签中提供该JS的引用即可。

"scripts": [ "./node_modules/my-exteranl-library/dist/x.js"]

方法2

在创建NPM软件包时不指定您的第三方依赖性 从您的酷图书馆的package.json文件中删除条目

"dependencies": { "my-exteranl-library": "^1.1.0" <-- Remove this } 并使用脚本标记通过index.html文件中的CDN将js直接添加到新创建的应用程序中

<script src="https://demo-cdn.com/ajax/libs/my-exteranl-library/dist/x.js"></script>

通过第三种方式,您可以通过在库中编写代码来下载JS,这将很快在此处共享。

答案 5 :(得分:0)

关于OP试图添加Hammer.js的特定示例。只需npm install Hammerjs然后编辑您的main.ts文件并添加import 'hammerjs',它将在全球范围内可用。

另请参阅this文章。

答案 6 :(得分:0)

有两种方法可以解决此问题:

1)在您的库中,将@angular/materialhammerjs指定为对等依赖项,以便所有将要使用您的库的应用程序都必须自己提供该库(这意味着每个应用程序都会拥有自己的angular.json,其中scripts属性包含hammerjs js文件)

2)使用ng-cli-packagr-tasks自定义构建步骤将hammen.min.js的{​​{1}}文件从node_modules到库的dist,并在代码中使用相对导入。

让我详细解释步骤2:

您想使用诸如require('../dependencies/hammer.min.js')之类的相对导入,但这将导致错误,因为在构建库之后,../dependencies/hammer.min.js将导致不确定的位置。为确保每次不仅将.ts文件神奇地转换为.js文件,而且还将静态.js文件复制到dist的特定目录库输出,则使用ng-cli-packagr-tasks。在构建阶段之后,ng-cli-packagr-tasks将使用glob复制文件,以便在应用程序中安装库之后,静态.js文件也将被捆绑在一起。这意味着导入import('../dependencies/hammer.min.js).then()将始终导致您自己提供的文件。

答案 7 :(得分:0)

要从资产外部加载js文件

创建服务文件,将文件添加到资产并在数组中写入路径。

import { Injectable } from "@angular/core";


    declare var document: any;
    @Injectable({
        providedIn:'root'
    })
    export class ScriptService {
      private scripts: any = {};

      constructor() {
        ScriptConstant.forEach((script: any) => {
          this.scripts[script.name] = {
            loaded: false,
            src: script.src
          };
        });
      }

      load(...scripts: string[]) {
        var promises: any[] = [];
        scripts.forEach(script => promises.push(this.loadScript(script)));
        return Promise.all(promises);
      }
      loadAll() {
        var promises: any[] = [];
        ScriptConstant.forEach(script => {
          // promises.push(delay(1000));
          promises.push(this.loadScript(script.name));
        });
        return Promise.all(promises);
      }

      loadScript(name: string) {
        return new Promise((resolve, reject) => {
          //resolve if already loaded
          if (this.scripts[name].loaded) {
            resolve({ script: name, loaded: true, status: "Already Loaded" });
          } else {
            //load script
            let script = document.createElement("script");
            script.type = "text/javascript";
            script.src = this.scripts[name].src;
            if (script.readyState) {
              //IE
              script.onreadystatechange = () => {
                if (
                  script.readyState === "loaded" ||
                  script.readyState === "complete"
                ) {
                  script.onreadystatechange = null;
                  this.scripts[name].loaded = true;
                  resolve({ script: name, loaded: true, status: "Loaded" });
                }
              };
            } else {
              //Others
              script.onload = () => {
                this.scripts[name].loaded = true;
                resolve({ script: name, loaded: true, status: "Loaded" });
              };
            }
            script.onerror = (error: any) =>
              resolve({ script: name, loaded: false, status: "Loaded" });
            document.getElementsByTagName("body")[0].appendChild(script);
          }
        });
      }
    }

    interface Scripts {
        name: string;
        src: string;
      }
      export const ScriptConstant: Scripts[] = [
        { name: "multislider", src: "assets/js/multislider.js" },

      ];

在需要的地方注入此ScriptService并像这样加载js库

this.script.load('multislider').then(data => {
    console.log('script loaded ', data);
}).catch(error => console.log(error));

答案 8 :(得分:-2)

您不能这样做,这是ng-packagr的行为,每次尝试将资源添加到资源库时,都会出现该错误。 查看此讨论以寻求可能的解决方案:https://github.com/angular/angular-cli/issues/11071