Невозможно опустить зависимости PrimeNG, используя внешние компоненты Webpack в приложении Angular - PullRequest
0 голосов
/ 09 февраля 2020

Я пытаюсь создать библиотеку 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, больше ничего. Как это вообще работает, кто-нибудь может мне сказать?

...