Je crée une bibliothèque angular (version 6) qui est basée sur angular matériel pour lequel j'ai besoin d'inclure la bibliothèque hammer js).
Je sais que dans angular 6 nous pouvons ajouter la bibliothèque js externe dans le angular.json
sous la configuration du projet. Mais cela ne fonctionne pas en cas de bibliothèque ci-dessus. J'ai essayé d'ajouter la bibliothèque externe de la manière suivante.
"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"
]
}
}
}
Mais je reçois cette erreur.
La validation du schéma a échoué avec les erreurs suivantes: Le chemin de données "" ne doit PAS avoir de propriétés supplémentaires (scripts).
Veuillez suggérer quelle est la bonne façon d'ajouter un fichier js externe dans la bibliothèque angular.
ajoutez d'abord la bibliothèque dans index.html ou dans
"scripts": [
"node_modules/hammerjs/hammer.min.js"
]
npm install d3 - enregistrer
npm install @ types/d3 --save-dev
Si la bibliothèque n'a pas de saisies disponibles dans @ types /, vous pouvez toujours l'utiliser en lui ajoutant manuellement des saisies:
typings.d.ts
fichier dans votre src/
dossier. Ce fichier sera automatiquement inclus en tant que définition de type globale.Puis dans src/typings.d.ts
, ajoutez le code suivant:
declare module 'typeless-package';
Enfin, dans le composant ou fichier qui utilise la bibliothèque, ajoutez le code suivant:
import * as typelessPackage from 'typeless-package';
typelessPackage.method();
veuillez suivre le lien
Pour charger le fichier js en externe à partir des ressources
créer un fichier de service ajouter un fichier aux actifs et écrire le chemin dans le tableau.
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" },
];
Injectez ce ScriptService partout où vous en avez besoin et chargez des bibliothèques js comme celle-ci
this.script.load('multislider').then(data => {
console.log('script loaded ', data);
}).catch(error => console.log(error));
Voici donc deux problèmes possibles que nous devons résoudre
1) Comment ajouter la référence de JS externe dans le projet principal angular (projet de démonstration)
2) Comment ajouter la référence de JS externe dans le package NPM.
La solution pour le 1er scénario est:
Indiquez la référence de votre JS externe dans votre angular.json
fichier du projet principal angular dans une balise de script et fournissez le chemin de votre package à partir de votre dossier node_modules de bibliothèques comme celui-ci.
"scripts": [ "./projects/my-cool-library/node_modules/my-exteranl-library/dist/x.js"]
La solution pour le 2ème scénario est:
approche 1
Alors maintenant, vous avez créé le package NPM à partir de votre bibliothèque et vous allez l'utiliser dans différents projets. évidemment, votre dépendance de package tiers sera téléchargée automatiquement une fois que vous aurez téléchargé votre package, il vous suffit de fournir la référence de ce JS dans la balise de script de angular.json
fichier du nouveau projet.
"scripts": [ "./node_modules/my-exteranl-library/dist/x.js"]
approche 2
Ne spécifiez pas votre dépendance tierce lors de la création de votre package NPM, supprimez l'entrée de package.json
fichier de votre bibliothèque cool
"dependencies": { "my-exteranl-library": "^1.1.0" <-- Remove this }
et ajoutez le js directement dans l'application nouvellement créée via CDN dans le fichier index.html à l'aide de la balise script
<script src="https://demo-cdn.com/ajax/libs/my-exteranl-library/dist/x.js"></script>
Il existe une 3ème façon de télécharger le JS en écrivant le code dans votre bibliothèque que vous partagerez ici sous peu.
retirer ../
avant le chemin de node_modules
"scripts": [
"node_modules/hammerjs/hammer.min.js"
]
Vous devriez essayer la commande ci-dessous si vous avez utilisé angular version 1.x auparavant. Et cela fonctionne pour moi.
ng update @angular/cli --migrate-only --from=1.7.4
Il existe deux façons possibles de résoudre ce problème:
1) Dans votre bibliothèque, spécifiez @angular/material
Et hammerjs
comme dépendances entre pairs afin que toutes les applications qui utiliseront votre bibliothèque sont nécessaires pour fournir la bibliothèque eux-mêmes (cela signifie que chaque application aura son propre angular.json
avec la propriété scripts
contenant le fichier hammerjs
js)
2) Utilisez ng-cli-packagr-tasks
étapes de construction personnalisées pour copier un fichier hammen.min.js
De node_modules
Vers la dist d'une bibliothèque et utilisez l'importation relative dans votre code.
Permettez-moi d'expliquer l'étape 2 plus en détail:
vous voulez utiliser une sorte d'importation relative comme require('../dependencies/hammer.min.js')
mais cela entraînera une erreur car après la construction de la bibliothèque, ../dependencies/hammer.min.js
conduira à un endroit incertain. Pour vous assurer que chaque fois non seulement vos fichiers .ts
Seront transposés comme par magie dans des fichiers .js
Mais aussi les fichiers statiques .js
Seront copiés dans un certain répertoire d'un dist
sortie d'une bibliothèque, vous utilisez ng-cli-packagr-tasks
. Après la phase de construction, ng-cli-packagr-tasks
Copiera les fichiers à l'aide de glob
afin qu'après avoir installé la bibliothèque dans votre application, les fichiers statiques .js
Soient également regroupés. Cela signifie que l'importation import('../dependencies/hammer.min.js).then()
mènera toujours au fichier que vous avez fourni par vous-même.