Использование нескольких угловых элементов в качестве веб-компонентов в угловом проекте
Учитывая три проекта @angular, все используют v6.1.9: host
, alpha
, а также beta
alpha
а также beta
создайте и определите веб-компонент, каждый из которых использует @ angular / elements как таковой:
constructor(private injector: Injector) {}
ngDoBootstrap() {
const config: NgElementConfig = { injector: this.injector };
const component= createCustomElement(component, config);
customElements.define("alpha-component", component); // beta-component respectively
}
alpha
а также beta
построены с использованием ng build --prod --output-hashing none
а затем запускается сценарий посткомпиляции для объединения полученных файлов в следующем порядке: scripts.js, styles.js, runtime.js, main.js
,
polyfills.js пропускается, потому что main.ts
при загрузке библиотеки проверит, были ли уже использованы использованные полифилы (например, чтобы не пытаться переопределить zone.js).
Результирующие связки alpha-component.bundle.js
а также beta-component.bundle.js
,
host
ссылается на вышеупомянутые связки в <head>
из index.html
с <script defer>
теги.
Если на пакеты ссылаются в порядке alpha
затем beta
, Я увижу alpha
пытаясь загрузить дважды; В обратном порядке я увижу beta
пытаясь загрузить дважды
Поскольку первый ссылочный пакет пытается дважды загрузиться, он пытается определить веб-компонент для пакета дважды, что приводит к ошибке и никогда не регистрирует веб-компонент второго ссылочного пакета.
Цель состоит в том, чтобы иметь возможность создавать множество веб-компонентов, используя @angular, а затем использовать их внутри других @angular или insert framework here
технологии.
3 ответа
К сожалению, конкатенация пакетов здесь не работает, б / к веб-пакет использует глобальную переменную. Переменная, созданная альфа-комплектом, будет перезаписана переменной бета-комплекта.
Вы можете переименовать эту переменную в пакетах, или вы можете использовать [1], и это ключ --single-bundle.
Чтобы начать, забудьте о том, что readme говорит о внешнем. Это метод дальнейшей оптимизации, где хост, альфа и бета могут использовать одни и те же библиотеки. Это предотвращает загрузку Angular несколько раз.
Возможно, вам также интересна моя серия блогов об Angular Elements [2].
С наилучшими пожеланиями, Манфред
Я использовал специальный конструктор angular, чтобы экспортировать собранный пакет angular с уникальным пространством имен, используя настраиваемую конфигурацию веб-пакета для конструктора angular.
Установите пакет @angular-builders / custom-webpack
Создайте собственный файл конфигурации веб-пакета. например. extra-webpack.config.js.
module.exports = { output: { chunkLoadingGlobal: 'webpackChunkModuleName', library: 'ModuleName' }
Укажите имя своего приложения или любое уникальное имя для библиотеки chunkLoadingGlobal &.
Примечание . Эти свойства соответствуют webpack 5, который используется в angular 12+. Пожалуйста, обратитесь к документации webpack для более старых версий webpack.
- Использование @ угловые строители / заказом WebPack в качестве строителя вместо @ углового DevKit / сборка-угловой и добавить customWebpackConfig объекта в angular.json.
"builder": "@angular-builders/custom-webpack:browser", ..... "customWebpackConfig": { "path": "extra-webpack.config.js", "mergeStrategies": { "externals": "prepend" } }
- Теперь, когда вы запустите ng build, ваше приложение будет построено с использованием настраиваемого конструктора с настраиваемой конфигурацией веб-пакета. Аналогичная конфигурация для другого приложения, экспортированного как веб-компоненты, и несколько веб-компонентов могут использоваться в одном и том же приложении-контейнере без каких-либо ошибок или конфликтов / загрязнения пространства имен.
Я использую советы Манфреда Штайера, и это работает, поэтому я разработаю здесь его ответ, приведя более подробный рабочий пример (на основе моего случая - Angular 8, я делаю это на MacOs):
На ваше
alpha
веб-компонент (который представляет собой отдельный угловой проект
<alpha>
) выполните следующие команды
npm install ngx-build-plus -S
ng update ngx-build-plus --force
ng add ngx-build-plus
ng g ngx-build-plus:wc-polyfill
ng g ngx-build-plus:externals
(это создаст файл
webpack.externals.js
в вашем основном каталоге проекта), а затем в
package.json
по ключу
scripts
Добавляю / редактирую ключ:
"build:alpha:externals": "ng build --output-hashing none --extra-webpack-config webpack.externals.js --prod --single-bundle true --project alpha && cat dist/alpha/polyfill-webcomp-es5.js dist/alpha/polyfills-es5.js dist/alpha/scripts.js dist/alpha/main-es5.js > dist/alpha.js"
и теперь я создаю веб-компонент:
npm run build:alpha:externals
это создаст файл
dist/alpha.js
- так же, как вы строите
beta.js
(в бета-проекте) - и в вашем
host
вы можете добавить оба в свой
index.html
от
<head>
...
<script src="./assets/web-components/alpha.js" type="text/javascript"></script>
<script src="./assets/web-components/beta.js" type="text/javascript"></script>
...
</head>
и оба должны работать одновременно