AOT 编译器 - 包括延迟加载的外部模块
AOT compiler - include lazy loaded external module
我正在尝试将外部模块(托管在 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) 这里的第一个问题是 AOT 编译器不编译你的模块(node_modules
文件夹默认被排除在外),所以你必须将它包含在你的 ts 的 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
数组中,因为 typescript 会排除它
Files included using "include" can be filtered using the "exclude"
property
详情见the doc
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
,因为 angular 不会为 index.d.ts
创建 ngfactory
文件,而 @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
之后写了一个非常简单的节点脚本 运行。它确实是一个 post 安装脚本。它将源文件从 node_modules
复制到主项目下的文件夹中。然后它更新对主路由文件中延迟加载模块的引用。
它对我的团队非常有效,我们大大提高了应用性能。
脚本简短,文档齐全,请查看
https://gist.github.com/insanediv/8b4ebba06824a3eb8233e10287a1cdcd
我正在尝试将外部模块(托管在 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) 这里的第一个问题是 AOT 编译器不编译你的模块(node_modules
文件夹默认被排除在外),所以你必须将它包含在你的 ts 的 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
数组中,因为 typescript 会排除它
Files included using "include" can be filtered using the "exclude" property
详情见the doc
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
,因为 angular 不会为 index.d.ts
创建 ngfactory
文件,而 @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
之后写了一个非常简单的节点脚本 运行。它确实是一个 post 安装脚本。它将源文件从 node_modules
复制到主项目下的文件夹中。然后它更新对主路由文件中延迟加载模块的引用。
它对我的团队非常有效,我们大大提高了应用性能。
脚本简短,文档齐全,请查看
https://gist.github.com/insanediv/8b4ebba06824a3eb8233e10287a1cdcd