在Angular 2中配置子模块的正确方法是什么,以便它能在AOT和汇总之后工作?我不关心延迟加载,并且很乐意将所有子模块捆绑在一起,但是loadChildren
是引用子模块并使用正确的<router-outlet>
的最干净的方法,尽管我尝试了各种方法,没有一种方法可以用于开发和生产。
我按照AOT cookbook中的说明准备我的应用以进行部署。我的模块结构是root&gt;帐户&gt; admin,我希望管理员路由加载到帐户组件定义的出口。
以下是帐户模块的路由器配置:
import { NgModule } from '@angular/core';
import { AdminModule } from './admin/admin.module';
const accountRoutes: Routes = [{
path: 'account',
component: AccountComponent,
children: [
{ path: 'setup', component: SetupComponent },
{ path: 'admin', loadChildren: () => AdminModule }
]
}];
这在开发中有效,但NGC编译失败了Error: Error encountered resolving symbol values statically. Reference to a local (non-exported) symbol 'accountRoutes'.
我添加了导出到accountRoutes
,但这也无法使用Error: Error encountered resolving symbol values statically. Function calls are not supported.
进行编译。
一个建议是使用字符串而不是函数,以便NGC可以编译代码:
loadChildren: 'app/account/admin/admin.module#AdminModule'
这在开发中有效并且编译成功,但编译的应用程序将无法运行,因为SystemJS不可用。错误是:
ERROR Error: Uncaught (in promise): TypeError: System.import is not a function
TypeError: System.import is not a function
at t.loadFactory (build.js:6)
at t.load (build.js:6)
at t.loadModuleFactory (build.js:12)
我尝试在生产版本中包含SystemJS,但它无法找到单独的模块文件app/account/admin/admin.module.ngfactory
- 汇总后所有内容都在一个build.js中。可能有一种方法可以使用单独的汇总来构建每个子模块,但这需要做很多工作。
我找到了引用导出函数的建议:
export function loadAdminModule() {
return AdminModule;
}
loadChildren: loadAdminModule
这在开发中有效,但在生产中,运行时编译器不可用,因此它会记录build.js:1 ERROR Error: Uncaught (in promise): Error: Runtime compiler is not loaded
。
可以修改辅助函数,使其在生产中通过引用NgFactory来工作,但这在开发中不起作用。
import { AdminModuleNgFactory } from '../../../aot/src/app/account/admin/admin.module.ngfactory';
export function loadAdminModule() {
return AdminModuleNgFactory;
}
loadChildren: loadAdminModule
是否有支持使用loadChildren
的方式,以便它可以使用AOT食谱中的说明?是否更好地使用webpack?
答案 0 :(得分:2)
对于有同样问题的人,这里是我正在使用的临时解决方法。希望很快会有更好的答案。
我现在在专用文件submodules.ts
中定义我的子模块。我有两个版本的此文件,submodules-jit.ts
用于开发,submodules-aot.ts
用于AOT /汇总部署到生产。我gitignore submodules.ts
并在我的npm start
和npm build:aot
脚本中添加了命令,替换为正确的脚本。
// submodules-jit.ts
import { AdminModule } from './account/admin/admin.module'
export function adminModule(): any { return AdminModule; }
// submodules-aot.ts
import { AdminModuleNgFactory } from '../../aot/src/app/account/admin/admin.module.ngfactory'
import { AdminModule } from './account/admin/admin.module'
export function adminModule(): any { return AdminModuleNgFactory; }
export function adminModuleKeep(): any { return AdminModule; }
必须在AOT文件中引用AdminModule才能保留它。
然后我在我的路线中使用adminModule
功能:
import { adminModule } from '../submodules'
{ path: 'admin', loadChildren: adminModule }
最后为方便起见,npm脚本会放入正确的文件中。
"build:aot": "cp src/submodules-aot.ts src/app/submodules.ts && ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
"start": "cp src/submodules-jit.ts src/app/submodules.ts && concurrently \"npm run build:watch\" \"npm run serve\""
毋庸置疑,这是一个可怕的黑客攻击,但它保留了路由文件的清洁和大部分的邪恶在一个地方。
答案 1 :(得分:0)
在我的情况下,我解决了从外部模块加载路线的提示,然后阅读this issue on angular/cli issue page。
所以,我出来重构我的路线:
import { TestModule } from './pathToModule/test.module';
export function exportTestModule() {
return TestModule;
}
. . .
{
path: 'test',
loadChildren: exportTestModule
}
要:
. . .
{
path: 'test',
loadChildren: './pathToModule#TestModule'
}