Я пытаюсь создать библиотеку Angular с пользовательской конфигурацией Webpack, где я указываю настройку externals
, чтобы исключить определенные зависимости из вывода компиляции. И все работает нормально, все внешние компоненты фактически исключены ... за исключением PrimeNG!
Примечание: вместо ng-packagr я использую Angular 8 с пользовательским компоновщиком ngx-build-plus:browser
, но я думаю, что это не имеет значения в этом случае. Я настроил его так, чтобы он правильно собирал библиотеку. И это так, за исключением упомянутой проблемы.
Я запускаю сборку с этой командой: ng build --extra-webpack-config libs/web-templates/extra-webpack.config.js --project web-templates --single-bundle
.
Вот как выглядит мой импорт в модуле основной библиотеки:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { TreeTableModule } from 'primeng/treetable';
import { MultiSelectModule } from 'primeng/multiselect';
Я также пробовал разные пути для импорта основных модулей, но это не помогло:
import { TreeTableModule } from 'primeng/components/treetable/treetable';
import { MultiSelectModule } from 'primeng/components/multiselect/multiselect';
В обоих случаях я использовал это extra-webpack.config.js
:
module.exports = {
output: {
libraryTarget: 'umd' // super-important
},
externals: {
"rxjs": "rxjs",
"rxjs/operators": "rxjs/operators",
"@angular/core": "@angular/core",
"@angular/common": "@angular/common",
"@angular/forms": "@angular/forms",
"@angular/platform-browser": "@angular/platform-browser",
"file-saver": "file-saver",
"lodash": "lodash",
"moment": "moment",
// 1) for the case with longer paths to primeng
"primeng/components/treetable/treetable": "primeng/components/treetable/treetable",
"primeng/components/multiselect/multiselect": "primeng/components/multiselect/multiselect",
// 2) for the case with normal paths to primeng
"primeng/treetable": "primeng/treetable",
"primeng/multiselect": "primeng/multiselect",
// that's just for importing some TypeScript interfaces, not compiled actually, so can be removed
"primeng/api": "primeng/api"
}
};
В результате скомпилированный вывод не содержит @angular/core
, rxjs/operators
и все другие зависимости, кроме PrimeNG. Например, вот фрагмент вывода с зависимостью rxjs / operator:
/***/ "rxjs/operators":
/*!*********************************!*\
!*** external "rxjs/operators" ***!
\*********************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_rxjs_operators__;
/***/ })
/******/ });
});
И все, операторы rx js успешно исключены из вывода, а также исходный код angular, момент JS и loda sh.
Однако для primeng TreeTableModule и MultiselectModule этого не происходит, что бы я ни делал. Вывод включает в себя все их источники. Я пытался совмещать их пути в конфигурации машинописи, пытался использовать короткие и полные пути (как показано выше).
Я даже пытался использовать относительные пути - без изменений:
// part of externals config
"../../../../node_modules/primeng/components/treetable/treetable": "../../../../node_modules/primeng/components/treetable/treetable",
"../../../../node_modules/primeng/components/multiselect/multiselect": "../../../../node_modules/primeng/components/multiselect/multiselect",
"node_modules/primeng/components/treetable/treetable": "node_modules/primeng/components/treetable/treetable",
"node_modules/primeng/multiselect": "node_modules/primeng/multiselect",
"node_modules/primeng/treetable": "node_modules/primeng/treetable"
Есть нет других мест , куда я импортирую PrimeNG. Я использую его точно так же, как Angular зависимости. Я думал, что это может быть из-за символа @
или /
в имени зависимости, но те же самые настройки прекрасно работают для rxjs/operators
.
Меня не волнует, как его интегрировать с хост-приложение (я уже сделал, успешно), я беспокоюсь только о выводе компиляции. Это 1,5 МБ (не минимизировано), потому что в нем много кода PrimeNG. Главный вопрос:
Почему он работает для других зависимостей и не работает для зависимостей PrimeNG при точно таких же условиях?
Если уместно, вот начало выходного файла (модуль UMD) для конфигурации веб-пакета, упомянутой выше. Интересное наблюдение: оно включает полные пути к основным компонентам (например, primeng/components/multiselect/multiselect
), но не включает короткие пути, такие как primeng/multiselect
, хотя они также перечислены во внешних пакетах веб-пакетов. Но в любом случае, источники primeng всегда присутствуют в выходных данных.
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("@angular/common"), require("@angular/core"), require("@angular/forms"), require("@angular/platform-browser"), require("file-saver"), require("lodash"), require("moment"), require("primeng/components/multiselect/multiselect"), require("primeng/components/treetable/treetable"), require("rxjs"), require("rxjs/operators"));
else if(typeof define === 'function' && define.amd)
define(["@angular/common", "@angular/core", "@angular/forms", "@angular/platform-browser", "file-saver", "lodash", "moment", "primeng/components/multiselect/multiselect", "primeng/components/treetable/treetable", "rxjs", "rxjs/operators"], factory);
else {
var a = typeof exports === 'object' ? factory(require("@angular/common"), require("@angular/core"), require("@angular/forms"), require("@angular/platform-browser"), require("file-saver"), require("lodash"), require("moment"), require("primeng/components/multiselect/multiselect"), require("primeng/components/treetable/treetable"), require("rxjs"), require("rxjs/operators")) : factory(root["@angular/common"], root["@angular/core"], root["@angular/forms"], root["@angular/platform-browser"], root["file-saver"], root["lodash"], root["moment"], root["primeng/components/multiselect/multiselect"], root["primeng/components/treetable/treetable"], root["rxjs"], root["rxjs/operators"]);
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
}
})(window, function(__WEBPACK_EXTERNAL_MODULE__angular_common__, __WEBPACK_EXTERNAL_MODULE__angular_core__, __WEBPACK_EXTERNAL_MODULE__angular_forms__, __WEBPACK_EXTERNAL_MODULE__angular_platform_browser__, __WEBPACK_EXTERNAL_MODULE_file_saver__, __WEBPACK_EXTERNAL_MODULE_lodash__, __WEBPACK_EXTERNAL_MODULE_moment__, __WEBPACK_EXTERNAL_MODULE_primeng_components_multiselect_multiselect__, __WEBPACK_EXTERNAL_MODULE_primeng_components_treetable_treetable__, __WEBPACK_EXTERNAL_MODULE_rxjs__, __WEBPACK_EXTERNAL_MODULE_rxjs_operators__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
// ... the rest of the file
ОБНОВЛЕНИЕ:
Мне удалось исключить внешние элементы primeng с помощью regexp в конфигурации webpack. Но это не очень практично.
// webpack config:
externals: [{
// ... my previous externals object
}, /primeng/]
В результате скомпилированный вывод содержит следующее:
else if(typeof define === 'function' && define.amd)
define([
"../../../../../../../node_modules/primeng/components/multiselect/multiselect.ngfactory",
"../../../../../../../node_modules/primeng/components/treetable/treetable.ngfactory",
"@angular/common", "@angular/core", "@angular/forms", "@angular/platform-browser", "file-saver", "lodash", "moment",
"primeng/components/common/shared",
"primeng/components/dropdown/dropdown",
"primeng/components/multiselect/multiselect",
"primeng/components/paginator/paginator",
"primeng/components/tooltip/tooltip",
"primeng/components/treetable/treetable",
"rxjs", "rxjs/operators"], factory);
Таким образом, кажется, что там добавлено много других зависимостей: "primeng / components / paginator / paginator "," primeng / components / tooltip / tooltip "," ../../../../../../../node_modules/primeng/components/treetable/treetable.ngfactory " и др. c. Хост-приложение вряд ли сможет обеспечить эти зависимости (особенно .ngfactory) ...
Но почему все эти зависимости появляются? В моем исходном коде я использую только импорт primeng/treetable
и primeng/multiselect
, больше ничего. Как это вообще работает, кто-нибудь может мне сказать?