AOT-компилятор - включает ленивый загруженный внешний модуль

Я пытаюсь включить внешний модуль (размещенный в репозитории git / npm) как модуль с отложенной загрузкой в ​​моем приложении Angular.

Я компилирую свой внешний модуль с помощью компилятора ngc:

node_modules/.bin/ngc -p tsconfig-aot.json

Вот как выглядит моя конфигурация компилятора:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "baseUrl": "src",
    "declaration": true,
    "outDir": "./release/src"
  },
  "files": [
    "./src/index.ts"
  ],
  "angularCompilerOptions": {
    "genDir": "release",
    "skipTemplateCodegen": true,
    "entryModule": "index#ExternalModule",
    "skipMetadataEmit": false,
    "strictMetadataEmit": true
  }
}

И в моем основном приложении я лениво загружаю данный модуль:

RouterModule.forRoot([
      { path: '', component: HomeComponent, pathMatch: 'full'},
      { path: 'lazy', loadChildren: './lazy/lazy.module#LazyModule'},
      { path: 'external', loadChildren: '@angular-universal-serverless/external-module/release#ExternalModule'}
])

Для целей компиляции я использую плагин @ngtools/webpack.

Компиляция JIT работает без проблем, но компиляция AOT выдает ошибку:

ERROR in ./src/ngfactory lazy
Module not found: Error: Can't resolve '/path/to/my/project/angular-universal-serverless/src/ngfactory/node_modules/@angular-universal-serverless/external-module/release/src/index.js' in '/Users/mtreder/Documents/private/work/angular-universal-serverless/src/ngfactory'
 @ ./src/ngfactory lazy
 @ ./~/@angular/core/@angular/core.es5.js
 @ ./src/main.server.aot.ts

Поэтому я решил проверить, что выход ngc компилятор (который вызывается плагином webpack):

node_modules/.bin/ngc -p tsconfig.server.aot.json

И на самом деле, мой модуль отсутствует в /path/to/my/project/angular-universal-serverless/src/ngfactory/node_modules каталог.

ls src/ngfactory/node_modules/
@angular        @nguniversal        @types          idb         ng-http-sw-proxy    rxjs            typescript-collections

Как я могу заставить ngc разместить данные модули в ngfactory выходной каталог?

Мое основное приложение можно найти здесь: https://github.com/maciejtreder/angular-universal-serverless/tree/externalModule

И внешний модуль здесь: https://github.com/maciejtreder/angular-external-module

1 ответ

Решение

1) Первая проблема заключается в том, что AOT-компилятор не компилирует ваш модуль (node_modules папка по умолчанию исключена), поэтому вы должны включить ее в files Вариант ваших тс конфигов:

tsconfig.browser.json

tsconfig.server.json

tsconfig.server.aot.json

"files": [
  "./node_modules/@angular-universal-serverless/external-module/release/src/externalComponent/external.module.d.ts"
],
"include": [
  "./src/main.browser.ts",
  "./src/app/lazy/lazy.module.ts",
  "./src/app/httpProxy/http-proxy.module.ts"
]

Мы не можем добавить это к includes массив, потому что машинопись исключит его

Файлы, включенные с помощью "include", могут быть отфильтрованы с помощью свойства "exclude"

Подробности смотрите в документе

2) Тогда\node_modules\@angular-universal-serverless\external-module\release\package.json должен иметь typings поле как:

"name": "@angular-universal-serverless/external-module",
"main": "./src/index.js",
"typings": "./src/externalComponent/external.module.d.ts", <=== this one

Мы должны использовать external.module.d.ts потому что угловой не создает ngfactory файл для index.d.ts в то время как плагин @ngtools/webpack создает карту для ContextElementDependency:

const factoryPath = lazyRoute.replace(/(\.d)?\.ts$/, '.ngfactory.ts');
// where lazyRoute === .../external-module/release/src/externalComponent/external.module.d.ts
const lr = path.relative(this.basePath, factoryPath);
this._lazyRoutes[k + '.ngfactory'] = path.join(this.genDir, lr);

Если вы не хотите менять package.json затем изменить loadChildren поле:

{ 
  path: 'external', 
  loadChildren: '@angular-universal-serverless/external-module/release/src/externalComponent/external.module#ExternalModule'
}

Возможно , уже слишком поздно, но я надеюсь, что это может кому-то помочь.

Я написал очень простой скрипт узла, который нужно запускать сразу после npm install. Это действительно сценарий после установки. Копирует исходные файлы изnode_modulesв папку под основным проектом. Затем он обновляет ссылки на ленивые загружаемые модули в основном файле маршрутов.

Это отлично сработало для моей команды, и мы значительно повысили производительность приложений.

Скрипт короткий и хорошо документированный, пожалуйста, ознакомьтесь с ним

https://gist.github.com/insanediv/8b4ebba06824a3eb8233e10287a1cdcd

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