我正在使用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文件的正确方法。
答案 0 :(得分:1)
您可以在 tsconfig.lib.jso n文件中添加外部库。
打开该文件,然后在 compilerOptios 中找到的 types 节点下添加您的欲望库。我举个例子。就我而言,我从项目节点模块中引用了该库。您可以使用Hammer.js库执行相同的操作。祝你好运
答案 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 /中没有可用的类型,您仍然可以通过手动为其添加类型来使用它:
然后在src / typings.d.ts中添加以下代码:
声明模块'typeless-package';
最后,在使用该库的组件或文件中,添加以下代码:
从'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/material
和hammerjs
指定为对等依赖项,以便所有将要使用您的库的应用程序都必须自己提供该库(这意味着每个应用程序都会拥有自己的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