angularライブラリ(バージョン6))を作成しています。これは、angularハンマー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"
]
}
}
}
しかし、私はこのエラーを受け取っています。
スキーマの検証が次のエラーで失敗しました:データパス ""に追加のプロパティ(スクリプト)を含めることはできません。
angularライブラリに外部jsファイルを追加する正しい方法を教えてください。
最初にライブラリをindex.htmlまたはに追加します
"scripts": [
"node_modules/hammerjs/hammer.min.js"
]
npm install d3 --save
npm install @ types/d3 --save-dev
ライブラリのタイプが@ types /で利用できない場合でも、手動でタイプを追加して使用できます。
typings.d.ts
ファイルをsrc/
フォルダ。このファイルは、グローバルタイプ定義として自動的に含まれます。次に、src/typings.d.ts
、次のコードを追加します。
declare module 'typeless-package';
最後に、ライブラリを使用するコンポーネントまたはファイルに、次のコードを追加します。
import * as typelessPackage from 'typeless-package';
typelessPackage.method();
link に従ってください
アセットから外部で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 libsをロードします
this.script.load('multislider').then(data => {
console.log('script loaded ', data);
}).catch(error => console.log(error));
だからここに私たちが対処する必要がある2つの考えられる問題があります
1)メインに外部JSの参照を追加する方法angular project(demo project)
2)NPMパッケージに外部JSの参照を追加する方法。
1番目のシナリオのソリューションは:です
スクリプトタグのメインangularプロジェクトのangular.json
ファイルに外部JSの参照を提供し、このようにライブラリのnode_modulesフォルダーからパッケージのパスを提供します。
"scripts": [ "./projects/my-cool-library/node_modules/my-exteranl-library/dist/x.js"]
2番目のシナリオのソリューションは:です
アプローチ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 }
そして、scriptタグを使用してindex.htmlファイルのCDNを介して新しく作成されたアプリケーションにjsを直接追加します
<script src="https://demo-cdn.com/ajax/libs/my-exteranl-library/dist/x.js"></script>
ライブラリにコードを記述してJSをダウンロードできる3つ目の方法は、まもなくここで共有されます。
削除する ../
node_modulesのパスの前
"scripts": [
"node_modules/hammerjs/hammer.min.js"
]
以前にangularバージョン1.xを使用したことがある場合は、以下のコマンドを試してみてください。それは私にとってはうまくいきます。
ng update @angular/cli --migrate-only --from=1.7.4
この問題を解決する方法は2つあります。
1)ライブラリで@angular/material
およびhammerjs
をpeer dependencyとして指定して、ライブラリを使用するすべてのアプリケーションがライブラリ自体を提供する必要があるようにします(つまり、各アプリが独自のangular.json
を持ち、scripts
jsファイルを含むhammerjs
プロパティが含まれていること)
2) ng-cli-packagr-tasks
カスタムビルドステップを copyhammen.min.js
ファイルから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()
が常に、自分で提供したファイルにつながることを意味します。