如果在尝试升级过程中遇到问题,欢迎提出。
如果发现本指南存在遗漏/错误,请指出!
或者你遇到了新的问题并解决了,欢迎补充!
原文地址:记NG4 迁移到 NG6 的一次实践
官方指南:Angular Update Guide
前几天成功把项目从angular4
迁移到angular6
最新版本。(截止当天Angular
最新版本是:6.1.4
)
于是做个记录:
思路是更新angular
相关核心包到新版本之后,然后再自行修改依赖包的兼容性问题。
在开始之前,请先备份你的项目
确保你的环境满足以下要求
$ node -v
node >= 8.9.0
$ npm -v
npm >= 5.6.0
删除你项目根目录下的 package-lock.json 文件
首先更新你的Angular-Cli,请注意保持全局的和当前项目使用的版本一致。
// global
$ npm uninstall -g @angular/cli // 卸载旧版本cli。
$ npm cache clean // 清除缓存,确保卸载干净
// 安装当前最新版本cli V6 (required node.js>=8.9)
$ npm install -g @angular/cli@latest
// local
$ npm install @angular/cli
$ ng update @angular/cli
注:如果卸载全局包失败可以在本地目录下手动删除(window10)
C:\Users\ Flcwl
\AppData\Roaming\npm\node_modules
使用命令查看环境【确认无误】
$ ng -v
Angular CLI: 6.1.5
通过这一步,你的angular相关的配置信息将会从angular-cli.json
迁移至根目录下的angular.json
文件里。
@angular/core 现在依赖于:
- TypeScript 2.7
- RxJS 6.0.0
- tslib 1.9.0
因此,我们需要在项目下执行以下命令完成angular v6
以及相关依赖的升级(包括typescript
和 rxjs
):
$ ng update @angular/core
$ ng update
在官方指南里有说,如果用到了Angular Material
,则可以用以下命令更新
$ ng update @angular/material
执行完后将会自动完成相关的它的废弃的APIs
的迁移。
这里要注意的问题:
尽量全局和本地typescript
都使用统一的新版本
typescript
尽量使用v2.7
版本,做到最大化的向上向下兼容。
因为原先是NG4
的项目,可能有很多依赖包并不支持最新版本的typescript
。
所以我们使用尽可能低的能使用的版本可能能帮助我们减少很多麻烦。
尽管这样,升级之后仍然可能会有包的依赖不匹配问题。请逐个升级解决问题。
我的办法是逐个排查match error
,逐个升级到它的最新版本,避免不必要的故事发生。
实在不行,遇到有些插件即使是最新版本也不支持angular 6 | typescript 2.7
,那就弃用new issue
或者更换,实在不济就自行造轮。
从rxjs v5
跨度到 v6
, 变化还是是非常大的,我们可以使用Migration to RxJS 6 来完成RxJS 6
的一些迁移。
$ npm install -g rxjs-tslint
$ rxjs-5-to-6-migrate -p src/tsconfig.app.json
可以看到有个名为rxjs-compat
的兄弟包,它支持在RxJs 6中移除掉的功能。
建议升级完成后将rxjs-compat
移除。使用真正的v6
可参考使用rxjs-compat升级RxJS的限制
RXjs 6
使用过程中有很多变化:
- 运算符(operators) 统一在rxjs/operators
中引入
// 例如导入`debounceTime`操作符等,推荐这么用
import { map, debounceTime } from 'rxjs/operators'
Observable
创建方法工具库等统一在 rxjs
中引入import { Observable, fromEvent, Subject } from 'rxjs';
.pipe()
来调用source.pipe(
map(x => x + x)
).subscribe(printResult);
merge
、concat
…具体使用细节、变动请参考:RxJS v5.x to v6 Update Guide
这里我是从ng-zorro v0.5
直接跳到 v1.4
,遇到的问题蛮多的,拿出来说说
// 更新到最新版本
$ npm install ng-zorro-antd@latest --save
在注入NgZorroAntdModule
的模块里面,删除forRoot()
样式修复
情况一 无自定义样式
在angular.json
配置文件中找到styles
字段,添加对应样式:
"styles": [
+ "node_modules/ng-zorro-antd/src/ng-zorro-antd.min.css",
]
注:如果有其它包有样式导入的话都需要如上形式导入具体路径。
情况二 有自定义样式(摘自:NG-ZORRO v1 升级指南)
执行以下命令,降级 less 到 2.7 版本 为什么?
npm install less@2.7.0 -D
找到引入过 ng-zorro-antd 的样式文件,按照以下方式修改:
- @import "~ng-zorro-antd/**";
+ @import "../node_modules/ng-zorro-antd/**";
遇到的一些小细节
输入框
// v.5
<nz-input [(ngModel)]="abc">nz-input>
// v1.4
<input nz-input [(ngModel)]="abc">
对话框(自定义组件)
创建对话框时create
而不是open
传入对象属性必须统一使用nz
开头,变得更规范
返回实例化对象类型为NzModalRef
而不是NzModalSubject
需要.afterOpen()
和.afterClose()
产生Observable
回调监听
自定义组件向组件外通信使用close(result) | destroy(result)
方法而不能使用next(result)
// v.5
import {NzModalSubject} from 'ng-zorro-antd';
constructor(private modal: NzModalSubject) {}
...
// 向组件外通信
this.modal.next(value);
...
// v1.4
import { NzModalRef } from 'ng-zorro-antd';
constructor(private modal: NzModalRef) {}
...
// 对话框自定义组件向组件外通信(我采用这种方式)
this.modal.destroy(value);
...
注:如果使用Component模式,则需要在NgModule中的 declarations
和 entryComponents
加入自定义的Component
Module | Service
,在主模块中app.module.ts
的导入声明后就可以使用了,但是在懒加载的子模块中想要使用,需要在该子模块的Xxx.module.ts
里面再次声明。// 注入错误 谨记
StaticInjectorError: no provider for ComponentFactoryResolver
.ts
后缀。 .ts
后缀导致该module
无法识别的错误(搞得我莫名其妙,项目之前本人并没有参与开发)。{
path: 'Xxx',
// .ts 神坑
// loadChildren: './Xxx/Xxx.module.ts#XxxModule'
// Run OK~
loadChildren: './Xxx/Xxx.module#XxxModule'
},
注:ng4
貌似没有上述规则,迁移前都是和和气气的可以运行。
Over~
欢迎 补充 | 讨论 | 修正。