1. lazyload 的 path 变成相对路径了, 不过如果你用 ng update 的话, 依然可以不需要修改, cli config 好像能调支持绝对路径的写法.
const routes: Routes = [ { path: '', loadChildren: './home/home.module#HomeModule' }, ];
2. 新的 providers 依赖注入机制 tree shakeable (可树摇)
从前我们通过在 module.providers 或 component.providers 提供我们的服务生产方式.
即使最后没有任何组建 inject 这些服务,但是最终的 bundle js 里依然会有这些代码.这不好.
所以提供了一种新的写法 ProvideIn
import { Injectable, InjectionToken, inject, LOCALE_ID, Inject } from '@angular/core'; export let AbcServiceConfig = new InjectionToken<string>('AbcServiceConfig', { providedIn: 'root', factory: AbcServiceConfigFactory }); export function AbcServiceConfigFactory(): string { return inject(LOCALE_ID); } @Injectable({ providedIn: 'root', // useFactory : () => new AbcService('tata') }) export class AbcService { name = 'keatkeat' constructor( @Inject(AbcServiceConfig) private dada: string ) { this.name = dada; } }
写了 ProvideIn 就不需要去写 module.providers 了 (当然你要写还是可以的, 以前的机制依然可以使用,并没有冲突)
新的机制下,只要没有 inject 服务,那么 tree shake 可以完全把这个服务代码移除. 不会在最终的 bundle.js 里面.
我个人觉得这个新机制并不太容易理解. 我做了一些测试,得出了一些结论.
1. provideIn : 'root' 全局服务
-这个可以对应从前的 module.providers. 但有一点要注意.
module.providers 会因为 lazyload 而产生特别的结果 (本来 module.providers 应该是全局单列, 但是lazyload会把它变成不是全局)
而 providerIn : 'root' 一定是全局单列,即使你在 lazyload 的 module.component 才注入服务.
-angular bundle 很厉害, 虽然你表示 'root' 全局,但是如果在 firstload 的时候没有人注入服务,而是等到 lazyload 后才注入服务, angular bundle 会分开打包. 只有 lazyload 的 bundle.js 才有这个服务的代码.
-如果服务依赖其它服务, 那么必须确保其它服务也能在 root injector 里被找到. 比如上面代码 factory 里使用了 angular/core inject() 这个是有作用域概念的, 'root' = root injector.
-绝大部分的时候我们都应该使用 'root'.
2.provideIn : ServiceModule
简单说是这样, 用一个 module 把 service 包起来, 任何要使用这个 service 的人必须通过自己的 module 去 import或间接 import 这个 ServiceModule
它做的事情是把 ServiceModule 包好的服务放入 ComponentModule.providers 里 ComponentModule import ServiceModule = ComponentModule.providers : [...ServiceModule.Serivces]
这个主要的目的就是替代之前的写法. 因为 providers 不可以树摇和 lazyload 分 bundle 打包, 而替换成这个写法后就变得可以了.
3. 从前需要通过注入 pipe 才能完成, 现在很方便了.
import { formatDate, formatNumber, FormatWidth } from '@angular/common';