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