本文介绍了AOT编译器-包含延迟加载的外部模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将外部模块(托管在git/npm存储库中)作为延迟加载的模块包含在Angular应用程序中.

I am trying to include external module (hosted in git/npm repository) as lazy-loaded module in my Angular application.

我正在使用ngc编译器来编译我的外部模块:

I am compiling my external module with ngc compiler:

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

这是我的编译器配置的外观:

This is how my compiler config looks:

{
  "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
  }
}

在我的主应用中,我懒于加载给定的模块:

And in my main app I am lazy loading given module:

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插件.

For compilation purposes I am using @ngtools/webpack plugin.

JIT编译正常进行,但是AOT编译给我错误:

The JIT compilation works without any problems, but AOT compilation gives me error:

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插件在后台调用):

So I decided to check what is the output from ngc compiler (whic is called under the hood by the webpack plugin):

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

实际上,/path/to/my/project/angular-universal-serverless/src/ngfactory/node_modules目录中缺少我的模块.

And in fact, my module is missing in the /path/to/my/project/angular-universal-serverless/src/ngfactory/node_modules catalog.

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

如何强制ngc将给定的模块放置在输出目录中?

我的主要应用程序可以在这里找到: https://github.com/maciejtreder/angular-universal-serverless/tree/externalModule

My main application can be found here: https://github.com/maciejtreder/angular-universal-serverless/tree/externalModule

和此处的外部模块: https://github.com/maciejtreder/angular-external-module

推荐答案

1)这里的第一个问题是AOT编译器无法编译您的模块(默认情况下不包含node_modules文件夹),因此您必须包括它在ts configs的files选项中:

1) The first problem here is that AOT compiler doesn't compile your module(node_modules folder is excluded by default), so you have to include it in files option of your ts configs:

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数组中,因为打字稿会排除它

We can't add it to includes array because typescript will exclude it

文档

2)然后 \ node_modules \ @ angular-universal-serverless \ external-module \ release \ package.json 应该具有typings字段,例如:

2) Then\node_modules\@angular-universal-serverless\external-module\release\package.json should has typings field like:

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

我们必须使用external.module.d.ts,因为@ ngtools/webpack插件为ContextElementDependency创建映射时,angular不会为index.d.ts创建ngfactory文件.

We have to use external.module.d.ts because angular doesn't create ngfactory file for index.d.ts while @ngtools/webpack plugin creates map for 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字段:

If you don't want to change package.json then change loadChildren field:

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

这篇关于AOT编译器-包含延迟加载的外部模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 00:21