В этой статье я покажу вам, как создать Angular UMD-плагин с поддержкой AOT (Ahead-of-Time) и автономным развертыванием. Когда я сказал об автономном развертывании, я имел в виду, что основное приложение не имеет прямой связи с библиотекой плагинов и имеет независимый собственный цикл выпуска. Я попытался найти некоторые решения, и все они используют компилятор angular в производстве, но я не хочу включать компилятор в производственный комплект.
Этот пример основан на стандартном способе сборки angular library, который angular cli поддерживает начиная с версии 6 и простой rollup команда для сборки пакета UMD. Весь исходный код вы можете найти там https://github.com/iwnow/angular-plugin-example 👀.
Сначала давайте начнем с создания основного приложения angular и библиотеки плагинов.
ng new angular-plugin-example
cd angular-plugin-example
ng generate library plugin
Теперь у нас есть основное приложение и плагин. Мы хотим загрузить плагин во время выполнения, но основное приложение не должно ничего знать о библиотеке плагинов, поэтому ленивый модуль - не наш путь.
Для этого мы должны создать пакет UMD, который экспортирует наш плагин с фабрикой модулей и фабрикой компонентов (AOT), поэтому давайте создадим нашу библиотеку.
ng build plugin
После сборки нас интересуют файлы в каталоге dist / plugin / esm2015 / lib /. По умолчанию у нас нет файлов .ngfactory.js, это означает, что у нас нет фабрик для наших компонентов. Для создания фабрик нам нужно отредактировать projects / plugin / tsconfig.lib.json и установить для skipTemplateCodegen значение false.
"angularCompilerOptions": { "annotateForClosureCompiler": true, "skipTemplateCodegen": false, "strictMetadataEmit": true, "fullTemplateTypeCheck": true, "strictInjectionParameters": true, "enableResourceInlining": true }
Теперь, если мы запустим сборку, мы получим фабрики для нашего модуля и компонентов.
После сборки фабрик нам нужно объединить все файлы фабрик в один комплект UMD, для этого я буду использовать свертку с простой командой:
rollup dist/plugin/esm2015/lib/plugin.module.ngfactory.js \ --file src/assets/plugin.module.umd.js \ --format umd \ --name 'app.plugin'
Эта команда объединяет все необходимые файлы в один файл и копирует его в папку с ресурсами для простой загрузки из основного приложения. Теперь у нас есть файл, содержащий нашу библиотеку плагинов с фабриками экспорта для модуля и компонентов angular.
Все, что нам нужно, это просто загрузить этот файл в наше основное приложение и создать NgModuleRef с помощью этой команды:
const pluginModuleRef = pluginModuleFactory.create(appInjector);
Итак, как мы получаем ссылку на фабрику подключаемых модулей? Для этого мы можем загрузить файл с помощью fetch API, например, следующим образом:
fetch('/assets/plugin.module.umd.js') .then(response => response.text()) .then(source => { //eval source and get plugin module factory from exports object });
В файле мы видим, что наша фабрика экспортируется как PluginModuleNgFactory:
Таким образом, весь код, создающий экземпляр компонента из плагина, может выглядеть так:
В приведенном выше коде вы увидите, как мы загружаем модуль UMD с помощью фабрики компонентов AOT angular и создаем компонент в viewContainerRef основного приложения. Демо доступно на github: https://github.com/iwnow/angular-plugin-example. Надеюсь, это поможет вам найти правильный путь! 👻