Ответ 1
Что касается конкретного примера OP, пытающегося добавить hammer.js. Просто npm установите hammerjs, затем отредактируйте ваш файл main.ts и добавьте import 'hammerjs'
, тогда он будет доступен глобально.
Также см. эту статью.
Я создаю угловую библиотеку (версия 6), которая основана на угловом материале, для которого мне нужно включить библиотеку hammer js.
Я знаю, что в angular 6 мы можем добавить внешнюю библиотеку js в angular.json
под конфигурацией проекта. Но это не работает в случае вышеупомянутой библиотеки. Я попытался добавить внешнюю библиотеку следующим образом.
"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 файл в угловую библиотеку.
Что касается конкретного примера OP, пытающегося добавить hammer.js. Просто npm установите hammerjs, затем отредактируйте ваш файл main.ts и добавьте import 'hammerjs'
, тогда он будет доступен глобально.
Также см. эту статью.
remove ../
перед тем, как путь node_modules
"scripts": [
"node_modules/hammerjs/hammer.min.js"
]
Вы должны попробовать выполнить команду ниже, если раньше вы использовали угловую версию 1.x. И это работает для меня.
ng update @angular/cli --migrate-only --from=1.7.4
сначала добавьте библиотеку в 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
Вы можете добавить свою внешнюю библиотеку в файл tsconfig.lib.jso n.
Откройте этот файл и добавьте свою библиотеку желаний в узел types, который вы можете найти в compilerOptios. Я даю вам и пример. В моем случае я ссылался на библиотеку из моего модуля узла проекта. Вы можете сделать то же самое с вашей библиотекой hammer.js. Удачи
Итак, вот две возможные проблемы, которые нам нужно решить
1) Как добавить ссылку на внешний JS в основной angular проект (демо-проект)
2) Как добавить ссылку на внешний JS в пакет NPM.
Решение для 1-го сценария:
Укажите ссылку на ваш внешний JS в файле angular.json
основного angular проекта в теге script и укажите путь к вашему пакету из вашей папки library node_modules, например, так:
"scripts": [ "./projects/my-cool-library/node_modules/my-exteranl-library/dist/x.js"]
Решение для второго сценария:
Подход 1
Итак, теперь вы создали пакет NPM из вашей библиотеки и собираетесь использовать его в другом проекте. очевидно, что ваша зависимость от стороннего пакета будет автоматически загружена после загрузки пакета, вам просто нужно указать ссылку на этот JS в теге script файла angular.json
нового проекта.
"scripts": [ "./node_modules/my-exteranl-library/dist/x.js"]
Подход 2
Не указывайте стороннюю зависимость при создании пакета NPM
удалите запись из файла package.json
вашей классной библиотеки
"dependencies": {
"my-exteranl-library": "^1.1.0" <-- Remove this
}
и добавьте js непосредственно во вновь созданное приложение через CDN в файле index.html с помощью тега script
<script src="https://demo-cdn.com/ajax/libs/my-exteranl-library/dist/x.js"></script>
Существует 3-й способ, которым вы можете скачать JS, написав код в своей библиотеке, который вскоре будет здесь.
Есть два возможных способа решения этой проблемы:
1) В вашей библиотеке укажите @angular/material
и hammerjs
как равноправные зависимости, так что все приложения, которые будут использовать вашу библиотеку, должны сами предоставлять библиотеку (это означает, что у каждого приложения будет своя собственная angular.json
со свойством scripts
, содержащим js файл hammerjs
)
2) Используйте ng-cli-packagr-tasks
пользовательские шаги сборки, чтобы скопировать файл hammen.min.js
из node_modules
в библиотеку и использовать относительный импорт в своем коде.
Позвольте мне объяснить шаг № 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()
всегда приведет к файлу, который вы предоставили сами.
Загрузка файла 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));
Вы не можете, что поведение ng-packagr
, вы будете получать эту ошибку каждый раз, когда вы пытаетесь добавить активы в библиотеку.
проверьте это обсуждение для возможного решения: https://github.com/angular/angular-cli/issues/11071