Angular项目如何升级至Angular6步骤全纪录

前言

前段时间将所负责的 Angular2 项目升级到了 Angular5 版本,这两天又进行了升级至 Angular6 的尝试。总的来说,两次升级过程比较类似,也不算复杂。

2018年5月4日,Angular6.0.0版正式发布,新版本主要关注底层框架和工具链,目的在于使其变得更小更快。

特性的小改动:

  • animations: 只能使用 WA-polyfill 和 AnimationBuilder
  • animations: 在转换匹配器中暴露元素和参数
  • common: 在 NgIf 中使用非模板元素时更好的错误消息
  • common: 导出函数来格式化数字,百分数,货币和日期
  • compiler: 实现“enableIvy”编译选项
  • core: 添加绑定名称到内容更改错误

0. 项目特点

该项目有如下特点:

  • 历史悠久,项目庞大,源码文件数量近千
  • 业务代码为主,极少应用 Angular 高级特性(升级简单)
  • 采用 pug 编写 html 结构
  • 采用 Less 编写 css 样式
  • 采用 Express 和 http-proxy 实现 server 及后端 API 的代理
  • 采用 compodoc 生成文档
  • 采用自开发的 @lzwme/simple-mock 实现 API mock
  • 采用 Fis3 编译,项目源码中深度使用了 fis3 的一些文件引用特性
  • 采用 webpack 和 karma、jasmine 配置和执行单元测试
  • 采用 styleLint、tsLint、husky 和 prettier 执行编码风格校验及格式化处理

项目升级后也没有使用 @angular/cli,继续采用 fis3 作为编译工具。这一是因为许多历史悠久的代码风格无法通过 tslint 校验,ng build 根本无法执行通过;二是因为项目的部分代码编写和构建与发布流程使用了一些 fis3 的特性,改造成本较大。而且经过比对,@angular/cli 的编译过程并没有比 fis3 好很多。

下面简要介绍一下升级的过程和方法。

1. 更新 package.json 的依赖

将 Angular 依赖库改为 ^6.1.0 版本,并且注意项目依赖的 Angular 组件库的兼容版本更新。如我们的项目依赖有如下变更:

  • @ngx-translate/core 需要更新至 ^10.0.2 版本;
  • angular-tree-component 需要更新至 7.x 版本;
  • @ngrx/store 需要更新至 ^6.1.0 版本;

注意:一些组件库的 API 也会有不兼容更新,相关代码逻辑应作改进(可在升级完成后根据文档和错误提示去调试和修改)。

升级后的项目依赖参考:

{
 "devDependencies": {
 "@compodoc/compodoc": "^1.1.5",
 "@lzwme/simple-mock": "~0.0.8",
 "@types/core-js": "^0.9.46",
 "@types/jasmine": "~2.8.6",
 "@types/jasminewd2": "~2.0.3",
 "@types/node": "~8.9.4",
 "@types/webpack": "~2.2.14",
 "angular2-template-loader": "~0.6.2",
 "awesome-typescript-loader": "~3.2.3",
 "body-parser": "1.17.0",
 "cookie-parser": "1.4.3",
 "cross-env": "^5.1.6",
 "debug": "2.6.1",
 "ejs": "2.5.6",
 "express": "4.15.0",
 "fis-optimizer-htmlmin": "0.1.2",
 "fis-optimizer-png-compressor": "0.2.0",
 "fis-parser-less": "0.1.3",
 "fis-parser-pug": "0.0.1",
 "fis-postpackager-replace": "0.0.3",
 "fis3": "3.4.39",
 "fis3-deploy-local-supply": "0.0.2",
 "fis3-hook-commonjs": "0.1.27",
 "fis3-hook-node_modules": "2.3.1",
 "fis3-hook-relative": "2.0.3",
 "fis3-packager-deps-pack": "0.1.2",
 "fis3-parser-typescript": "^1.2.2",
 "fis3-postpackager-loader": "2.1.11",
 "fis3-preprocessor-cssprefixer": "0.0.2",
 "fis3-preprocessor-js-require-css": "0.1.3",
 "fis3-preprocessor-js-require-file": "0.1.3",
 "fis3-preprocessor-ng2-inline": "0.0.1",
 "fs-extra": "^6.0.1",
 "http-proxy": "1.16.2",
 "husky": "^0.14.3",
 "istanbul-instrumenter-loader": "^3.0.1",
 "jasmine-core": "^3.1.0",
 "karma": "^2.0.2",
 "karma-chrome-launcher": "^2.2.0",
 "karma-coverage": "^1.1.1",
 "karma-coverage-istanbul-reporter": "^2.0.1",
 "karma-jasmine": "^1.1.2",
 "karma-jasmine-html-reporter": "^1.1.0",
 "karma-mocha-reporter": "^2.2.5",
 "karma-remap-coverage": "^0.1.5",
 "karma-sonarqube-unit-reporter": "^0.0.14",
 "karma-sourcemap-loader": "~0.3.7",
 "karma-webpack": "^3.0.0",
 "less": "^3.0.4",
 "less-loader": "^4.1.0",
 "liftoff": "2.3.0",
 "lint-staged": "^7.1.3",
 "minimist": "1.2.0",
 "morgan": "1.8.1",
 "prettier": "^1.13.5",
 "pug": "^2.0.3",
 "pug-html-loader": "^1.1.5",
 "raw-loader": "~0.5.1",
 "serve-favicon": "2.4.1",
 "stylelint": "^9.4.0",
 "stylelint-config-prettier": "^4.0.0",
 "supervisor": "^0.12.0",
 "to-string-loader": "^1.1.5",
 "tslint": "^5.10.0",
 "typedoc": "^0.11.1",
 "typescript": "^2.8.3",
 "webpack": "~3.6.0"
 },
 "dependencies": {
 "@angular/animations": "^6.1.0",
 "@angular/common": "^6.1.0",
 "@angular/compiler": "^6.1.0",
 "@angular/core": "^6.1.0",
 "@angular/forms": "^6.1.0",
 "@angular/http": "^6.1.0",
 "@angular/platform-browser": "^6.1.0",
 "@angular/platform-browser-dynamic": "^6.1.0",
 "@angular/router": "^6.1.0",
 "@ngrx/router-store": "6.1.0",
 "@ngrx/store": "^6.1.0",
 "@ngx-translate/core": "^10.0.2",
 "@ngx-translate/http-loader": "^3.0.0",
 "angular-tree-component": "^7.2.1",
 "buffer": "4.9.1",
 "core-js": "^2.5.7",
 "fis-mod": "1.0.1",
 "is-buffer": "1.1.4",
 "jquery": "1.12.4",
 "moment": "2.18.1",
 "ngrx-store-freeze": "0.2.4",
 "ngrx-store-logger": "0.2.2",
 "process": "0.11.9",
 "reflect-metadata": "0.1.12",
 "rxjs": "^6.0.0",
 "rxjs-compat": "^6.2.2",
 "throttle-debounce": "^2.0.1",
 "zone.js": "0.8.26"
 }
}

2. 添加 rxjs-compat 依赖

为了兼容 rxjs 5 的用法,必须引入 rxjs-compat。

添加依赖:

yarn add rxjs-compat

然后在项目入口文件 main.ts 中引入它:

import 'rxjs-compat';

注意,后续的开发应有意识地以 rxjs6 的新写法去编码。

当然,如决定改掉 rxjs5 的旧写法,可以移除对 rxjs-compat 的引入,参照浏览器错误提示去一一修改即可。

3. 按官方指引和项目实际情况选择性操作

打开 Angular 官方升级指引网站 https://update.angular.io 按提示和项目实际情况操作。

实际上项目没有太多高级的用法,需要修改的内容并不多。大致有以下几点:

  • 如有用到 extends OnInit,应该为 implements OnInit 方式
  • 模板中如有用到 <template> 标签,将它改为 <ng -template>。全局查找和替换即可。
  • HttpModule 和 Http 应分别改用 HttpClientModule 和 HttpClient。HttpClient 支持拦截器,这可以在 http 请求过程中实现注入,实现更自由的逻辑,如角色权限验证等。项目中的 http 请求已经基于 Http 模块进行了封装,所以这一步可以忽略。但应考虑全局改进 http 封装,或者在后续的开发中采用 HttpClient。
  • 全局安装 rxjs-tslint,执行源码级的升级,主要是修改 rxjs@6 废弃的用法。这个操作会修改很多文件。
npm install -g rxjs-tslint
rxjs-5-to-6-migrate -p src/tsconfig.app.json

以上操作完成后,尝试启用项目构建编译,如无报错即已成功升级。

总结:

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • 利用Angular2的Observables实现交互控制的方法

    在Angular1.x中,我们使用Promise来处理各种异步.但是在angular2中,使用的是Reactive Extensions (Rx)的Observable.对于Promise和Observable的区别,网上有很多文章,推荐egghead.io上的这个7分钟的视频(作者 Ben Lesh).在这个视频的介绍中,主要说的,使用Observable创建的异步任务,可以被处理,而且是延时加载的.这篇文章里,我们主要针对一些在跟服务器端交互的时候遇到的问题,来看看Observable给我们

  • angular6 填坑之sdk的方法

    技术背景:angular + ant zorro 最为大型前端团队首选的前端技术框架,angular,在国内多少还是有些水土不服.本人将针对angular做个一系列的填坑分享. 坑一:sdk angular的sdk不属于各个模块,直接挂载在body下面, ant design直接使用sdk,导致任何的弹出层,如select,dropdown,picker等在弹出来的时候自动创建覆盖全局的sdk,需要点击sdk才能关闭已打开的下拉. 明显需要点击两次才能出现一个下拉是产品们不能接受的. 解决方案有

  • 详解从angular-cli:1.0.0-beta.28.3升级到@angular/cli:1.0.0

    现在Angular CLI在npm下通过@angular/cli来替代angular-cli,并且它只支持Node6.9.0或更高的版本,npm 3或更高的版本.所以在升级angular cli之前,请先升级node和npm. 如果你使用Angular CLI beta.28或更低的版本,你需要先卸载掉 angular-cli包: npm uninstall -g angular-cli npm uninstall --save-dev angular-cli 如果你忘记了更新npm,执行上面第

  • Angular(5.2->6.1)升级小结

    在前面的文章中也曾经分别提到过,angular6由于存在一些稍大的变化,所以不能像Angular4到Angular5那样基本无感地进行升级,这里结合官方提示,简单整理一下Angular5.2到目前稳定的6.1的升级要点. 事前准备 变更内容 除此之外,还需要确认如下内容: tsconfig.json: preserveWhitespaces设定为off(v6缺省设定) package.json中scripts的使用,所有的cli命令统一使用两个横线–传入参数(POSIX规范) ngModelCh

  • Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法

    前言 RxJS是一种针对异步数据流编程工具,或者叫响应式扩展编程:可不管如何解释RxJS其目标就是异步编程,Angular引入RxJS为了就是让异步可控.更简单.可是最近在升级中遇到了一些问题,下面就来给大家介绍下,给同样遇到这个问题发朋友们一些参考,下面话不多说了,来一起看看详细的介绍吧. Angular 5.0.5升级RxJS到5.5.3报错: ERROR Error: Uncaught (in promise): EmptyError: no elements in sequence Em

  • Angular2平滑升级到Angular4的步骤详解

    前言 Angular4终于在两天前发布了正式版本,那么怎么升级呢?其实Angular2和Angular4之间属于平滑过渡,并不像1和2之间颠覆性的重写代码. Angular4现已发布  http://www.jb51.net/article/109685.htm 为什么跳过Angular 3? 根据Angular团队首席开发Igor Minar的说法:随着Angular 2的发布,Angular团队引入了语义化版本控制规范,即:将语义化版本用三组数字来表示,按照major.minor.patch

  • angular 用Observable实现异步调用的方法

    Observable(可观察对象) Observable(可观察对象)是基于推送(Push)运行时执行(lazy)的多值集合. 拉取(Pull)和推送(Push) 拉取和推送是数据生产者和数据消费者之间通信的两种不同机制. 拉取:在拉取系统中,总是由消费者决定何时从生产者那里获得数据.生产者对数据传递给消费者的时间毫无感知(被动的生产者,主动的消费者) 推送:在推送系统中生产者决定何时向消费者传递数据,消费者对何时收到数据毫无感知(被动的消费者) js中的Promise和Observable 现

  • @angular前端项目代码优化之构建Api Tree的方法

    前颜(yan) 在前端项目的开发过程中,往往后端会给到一份数据接口(本文简称api),为了减少后期的维护以及出错成本,我的考虑是希望能够找到这么一种方法,可以将所有的api以某种方式统一的管理起来,并且很方便的进行维护,比如当后端修改了api名,我可以很快的定位到该api进行修改,或者当后端添加了新的api,我可以很快的知道具体是一个api写漏了. 于是,我有了构建Api Tree的想法. 一.前后端分离(Resful api) 在前后端分离的开发模式中,前后端的交互点主要在于各个数据接口,也就

  • angular中两种表单的区别(响应式和模板驱动表单)

    angular的表单 angular的表单分为两种,一种是响应式的表单,另一种是模板驱动表单.使用'@angular/forms'库中的FormGroup, FormControl,FormArray,FormBuilder 等类构建出的数据对象就是响应式的表单,在响应式的表单中,我们会在数据源里面进行各种操作,像添加校验等,在html文件中使用 formGroup,formGroupName,formControlName等将数据和视图进行绑定(需要引入ReactiveFormsModule)

  • 浅谈Angular7 项目开发总结

    由于公司需要,开始学习angular,这个传闻中学习曲线及其陡峭的前端框架,并开始写第一个用angular的项目,截止今天初步完成现有需求,顾在此做一次遇到问题的总结,以便知识的掌握. 一.在angular项目中,如何使用锚点 在常规项目中,使用锚点用来做"智能"定位效果时,只需这么写: <a href="#test" rel="external nofollow" >走你</a> <div id="tes

随机推荐