Использование нескольких угловых элементов в качестве веб-компонентов в угловом проекте

Учитывая три проекта @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].

С наилучшими пожеланиями, Манфред

[1] https://github.com/manfredsteyer/ngx-build-plus

[2] https://www.softwarearchitekt.at/post/2018/07/13/angular-elements-part-i-a-dynamic-dashboard-in-four-steps-with-web-components.aspx

Я использовал специальный конструктор angular, чтобы экспортировать собранный пакет angular с уникальным пространством имен, используя настраиваемую конфигурацию веб-пакета для конструктора angular.

  1. Установите пакет @angular-builders / custom-webpack

  2. Создайте собственный файл конфигурации веб-пакета. например. extra-webpack.config.js.

            module.exports = {
    output: {
        chunkLoadingGlobal: 'webpackChunkModuleName',
        library: 'ModuleName'
    }
    

Укажите имя своего приложения или любое уникальное имя для библиотеки chunkLoadingGlobal &.

Примечание . Эти свойства соответствуют webpack 5, который используется в angular 12+. Пожалуйста, обратитесь к документации webpack для более старых версий webpack.

  1. Использование @ угловые строители / заказом WebPack в качестве строителя вместо @ углового DevKit / сборка-угловой и добавить customWebpackConfig объекта в angular.json.
       "builder": "@angular-builders/custom-webpack:browser",
    .....
    "customWebpackConfig": {
       "path": "extra-webpack.config.js",
        "mergeStrategies": {
           "externals": "prepend"
         }
     }
  1. Теперь, когда вы запустите 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>

и оба должны работать одновременно

Другие вопросы по тегам