Angular 8.0 不再推荐使用字符串语法来配置延迟加载路由,而是推荐使用 EcmaScript 动态导入。import(specifier)
语法形式返回一个包含模块命名空间对象的 Promise。在 Promise 解析后,我们获取导出的 LazyModule。
之前
const routes: Routes = [{
path: 'lazy',
// The following string syntax for loadChildren is deprecated
loadChildren: './lazy/lazy.module#LazyModule'
}];
之后
const routes: Routes = [{
path: 'lazy',
// The new import() syntax
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}];
您也可以在 NativeScript Angular 中使用新的延迟加载语法!
动态导入提案已计划在 ES2020 中发布。它也被所有主流浏览器实现。由于它比较新,因此您需要告诉 TypeScript 在编译代码时使用最新的 EcmaScript 模块规范。打开您的 tsconfig.tns.json 文件并将 module
属性设置为 esNext
tsconfig.tns.json
{
"extends": "./tsconfig",
"compilerOptions": {
"module": "esNext",
"moduleResolution": "node"
}
}
重要提示! NativeScript Playground 目前不支持动态导入。在 Playground 中编写 NativeScript Angular 应用程序时,目前请坚持使用旧的延迟加载语法。
将所有路由迁移到新的语法可能相当繁琐。但是您可以告诉 TSLint 为您执行此操作!
首先,确保您的项目中安装了 TSLint
npm install tslint --save-dev
之后,安装由 Craig Spence 创建的 angular-lazy-routes-fix
TSLint 规则
npm install @phenomnomnominal/angular-lazy-routes-fix --save-dev
然后,将该规则添加到您的 TSLint 配置文件中。如果您没有配置文件,则只需创建一个新的 tslint.json
文件
tslint.json
{
"extends": [
"@phenomnomnominal/angular-lazy-routes-fix"
],
"rules": {
"no-lazy-module-paths": [true]
}
}
最后,使用 --fix
标志运行 TSLint
npx tslint -p tsconfig.json --fix
代码 linter 会找到所有旧延迟加载语法的使用情况,并将其替换为动态导入。
NativeScript 运行时并不原生支持 import()
语法。但是,借助 webpack 和 Angular,您可以在路由配置中使用它。当您使用 webpack 构建项目时,以下代码
const routes: Routes = [{
path: 'lazy',
loadChildren: () => import('./lazy/lazy.module').then(m => m.LazyModule)
}];
大致转换为
const routes: Routes = [{
path: 'lazy',
loadChildren: requireEnsure('./1.js').LazyModule
}];
文件 1.js 是 /lazy 路由的 延迟加载捆绑包。它包含名为 LazyModule
的 NgModule
以及它所依赖的所有 Components
、Directives
和其他 NgModules
。
旁注:1.js 不包含任何第三方包。相反,应用程序中任何地方所需的来自 node_modules 的所有包都将最终出现在名为 vendor.js 的捆绑包中。
延迟加载捆绑包 由 requireEnsure
函数从文件系统加载。该函数由 webpack 插入。如果您是为浏览器、Node 或 NativeScript 构建,则 requireEnsure
函数的定义会有所不同。
旁注:在 NativeScript 中,该函数的定义是从位于 nativescript-target for webpack 中的模板生成的。
对于 NativeScript,requireEnsure
函数的实现仅使用 require()
调用加载文件,然后对其进行缓存。因此,最终您永远不会在应用程序中实际发布动态 import()
,而是将其全部转换为传统的 CommonJS require()
。NativeScript 运行时通过从设备文件系统加载文件来实现 require()
函数。
整个模块加载故事中的主要要点是
import()
加载延迟加载模块。import()
并非原生支持,但在构建过程中 webpack 会将其替换为 require()
。