将 angular 4 项目升级到 angular 6 [英] upgrade angular 4 project to angular 6

查看:31
本文介绍了将 angular 4 项目升级到 angular 6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将现有的 angular 4 项目升级到 angular 6

我已按照

我是否遗漏了任何步骤,如何升级到 angular 6 而不是 angular 7

解决方案

升级到 Angular v6

有关如何升级到新 Angular 版本的详细信息的最佳资源是 https://update.angular.io/.即使您是从 v2 升级到 v6,它也会列出自 v2 到 v6 以来的所有重大更改!这是详细了解您需要在代码中更改哪些内容的好方法.

1:安装最新的 Angular CLI

第一步是确保您拥有最新的 CLI:

npm install -g @angular/cli

随着 Angular v6 的发布,Angular CLI 现在也被版本化为 Angular,这意味着在 Angular v5 之前,我们将使用 Angular CLI 1.x,现在 Angular CLI 也在 6.x 版上.它使它变得更容易!

2:ng 更新

不用说,请创建一个分支来更新您的项目,因为您永远不会知道升级到 Angular v6 后所有依赖项是否仍然有效.

所以首先,我们将从 @angular/cli 开始.为了让 ng update 命令在项目中工作,我们首先需要将 @angular/cli 版本更新为 6.x.

npm install --save-dev @angular/cli@latest

接下来,为 @angular/cli 运行 ng update 命令,然后是 @angular/core,然后是其他所需的包(rxjs, @angular/material):

ng 更新@angular/cling更新@angular/coreng更新@angular/materialng 更新 rxjs

一些项目结构文件已从 v5 更改为 v6.不再有 angular-cli.json,它已被 angular.json 取代.angular.json 的结构也发生了变化,以支持每个工作区的多个项目.当我们运行 ng update @angular/cli 时,所有需要的文件都会更新!

3:更新其他依赖项

我还喜欢在 Angular 升级期间更新项目使用的其他 npm 依赖项.npm 包 npm-check-updates 对这项任务非常有帮助.

npm install -g npm-check-updates

使用命令 ncu 检查哪些软件包有可用的更新.和 ncu -u 更新你的 package.json.

在更改 package.json 包的版本时,我个人也喜欢删除 node_module 并再次运行 npm i 以确保正确的版本在本地可用(并更新 package-lock.json).

4:更新 RxJS

所以,下一步是运行 ng serve 来检查代码是否一切正常.不要忘记验证 https://update.angular.io/ 的所有喙变化.>

尽管我们能够从 Angular v5(使用 RxJS v5)更新 RxJS 代码以使用管道运算符,但在我升级到 v6 的项目中,我忘记更改一些地方.为了帮助我们完成这项任务,我们可以安装 rxjs-tslint 来帮助我们删除所有已弃用的 RxJS 代码.

npm install -g rxjs-tslintrxjs-5-to-6-migrate -p src/tsconfig.app.json

作为关于进口的快速总结:

import { Subject } from 'rxjs/Subject';从'rxjs/BehaviorSubject'导入{BehaviorSubject};从 'rxjs/Observable' 导入 { Observable };导入 { of } from 'rxjs/observable/of;'

到:

import { BehaviorSubject, Subject, Observable, of } from 'rxjs';

或者,如果您还没有使用 RxJS 管道运算符:

import 'rxjs/add/observable/of';导入 'rxjs/add/operator/catch';导入 'rxjs/add/operator/do';导入 'rxjs/add/operator/map';导入 'rxjs/add/operator/mergeMap';导入 'rxjs/add/operator/switchMap';

import { of } from 'rxjs';import { map, switchMap, catchError, mergeMap } from 'rxjs/operators';

以下运算符也被重命名:

do ->轻敲抓住->捕获错误开关 ->全部切换终于->敲定

在我们的代码中,我们可以开始使用管道运算符.

来自:

this.http.get('url').do(控制台.log).map(results => results.data).订阅(结果 => {console.log('结果', 结果);});

致:

this.http.get('url').管道(tap(console.log),//旧的 'do' 操作符地图(结果 => 结果.数据)).订阅(结果 => {console.log('结果', 结果);});

更新 RxJS 代码后,您可能仍会收到有关来自第三方依赖项的 RxJS 错误.要解决此问题,请安装 rxjs-compat,一旦依赖项也升级了它们的代码,您就可以从项目中删除此包.

npm install --save rxjs-compat

5:简化核心服务的依赖注入

Angular v6 中引入的一项新功能称为tree-shakable providers".这意味着我们不再需要使用属性 providedIn 在模块中声明服务,这将允许服务摇树,这意味着如果它们不被使用,它们将不会成为一部分产品包.

import { Injectable } from '@angular/core';@Injectable({提供在:'根'})导出类 MyCoreService { }

我在项目的所有核心服务(全局范围)中应用了此功能,但我仍在使用具有不具有全局范围的服务的不可摇树提供程序.

这允许清理 CoreModule 中的 providers 部分.

6:更新 Angular Material(可选)

如果您在项目中使用 Angular Material,请不要忘记运行 ng update @angular/material 以更新材质依赖项.

从 v5 到 v6 的重大变化是我们在项目中导入 Material 模块的方式:

来自:

import {MdToolbar 模块,MdIcon 模块,MdButton 模块,MdMenuModule,卡模块来自'@angular/material';

致:

import { MatToolbarModule } from '@angular/material/toolbar';从'@angular/material/icon' 导入 { MatIconModule };从'@angular/material/button' 导入 { MatButtonModule };从'@angular/material/menu' 导入 { MatMenuModule };从'@angular/material/card' 导入 { MatCardModule };

现在每个模块都有自己的包.这也是我喜欢为第三方导入创建单独模块的原因之一,如本文中已经解释的那样.修复导入变得更加容易!

其他一些事情......我确实有一些自 Angular v2 以来创建的项目,在每次主要版本更新后,我通常只更新 package.json 并修复代码中的重大更改,这没问题.

由于 Angular CLI v6 中的项目结构发生了一些变化,我也决定通过使用 CLI 6 创建一个全新的项目并将 src 文件夹从旧项目复制到新项目来迁移项目.以下是一些受影响最大的变化.

对代码有一些影响的主要区别是 baseUrl: './' 来自 tsconfig.json.对于使用 CLI 1.x(用于 Angular v4 和 v5)创建的项目,默认情况下不存在此配置(但在 src/tsconfig.ap.json 中).将 baseUrl 移至根 tsconfig.json 会对 tsconfig.json 中声明的自定义路径以及延迟加载模块的路径产生影响.

之前 - tsconfig.json 中的自定义路径:

路径:{"@env/*": ["环境/*"]}

之后(使用 CLI v6 创建的单个项目):

路径:{"@env/*": ["src/环境/*"]}

并且需要使用相对路径声明延迟加载模块:

之前:

{ path: 'home', loadChildren: 'app/home/home.module#HomeModule' }

之后:

{ path: 'home', loadChildren: './home/home.module#HomeModule' }

如果你有嵌套模块,你还需要更新它们以使用相对路径:

之前(module1-routing.module.ts):

{ path: 'foo', loadChildren: 'app/module1/module2/module2.module#Module2Module' }

之后(module1-routing.module.ts):

{ path: 'foo', loadChildren: './module2/module2.module#Module2Module' }

CLI v6 命令也有一些变化.由于我的大多数专业应用程序在后端使用 Java,因此 ng build 的输出文件夹 (dist) 被配置为不同的路径.在 CLI 1.x 之前,有一个标志 (output-path -op) 可以在 ng build 命令 (ng build -op ../other/path) 中使用.使用 CLI v6,如果您需要使用不同的输出路径,则需要更新 angular.json 并从 ng build 中删除 -op 标志:

架构师":{建造": {"builder": "@angular-devkit/build-angular:browser",选项": {"outputPath": "../other/path",...}}}

I need to upgrade an existing angular 4 project to angular 6

I have followed the steps mentioned in the https://update.angular.io/

npm install -g @angular/cli@6
npm install @angular/cli@6
ng update @angular/cli
ng update @angular/core
ng update 

but these steps are landing in upgrading to angular 7 not angular 6

Screenshot of the result after running the ng update command:

Am I missing any steps, how to upgrade to angular 6 instead of angular 7

解决方案

Upgrading to Angular v6

The best resource with details on how to upgrade to a new Angular version is https://update.angular.io/. Even if you are upgrading from v2 to v6, it will list all the breaking changes since v2 to v6! It is a great way to know in details what you need to change in your code.

1: Instaling latest Angular CLI

First step is to make sure you have the latest CLI available:

npm install -g @angular/cli

With the release of Angular v6, the Angular CLI is now also versioned as Angular, meaning until Angular v5, we would use Angular CLI 1.x, and now Angular CLI is also on version 6.x. It makes it much easier!

2: ng update

Needless to say, please do create a branch to update your project, as you’ll never know if all dependencies will still work after upgrading to Angular v6.

So first, we will start with @angular/cli. In order for the ng update command to work inside the project, we need first to update the @angular/cli version to 6.x.

npm install --save-dev @angular/cli@latest

Next, run the ng update command for @angular/cli, then @angular/core and then for the other packages required (rxjs, @angular/material):

ng update @angular/cli
ng update @angular/core
ng update @angular/material
ng update rxjs

Some project structure files have changed from v5 to v6. There is no angular-cli.json anymore, it has been replaced by angular.json. The structure of angular.json also has changed to support multiple projects per workspace. When we run ng update @angular/cli all the required files will be updated!

3: Updating other dependencies

I also like to update the other npm depedencies used by the project during an Angular upgrade. The npm package npm-check-updates is really helpful for this task.

npm install -g npm-check-updates

Use the command ncu to check what packages have updates available. And ncu -u to update your package.json.

When changing versions of package of package.json, I personally also like to delete the node_module and run npm i again just to make sure the correct versions are availavle locally (and also update package-lock.json).

4: Updating RxJS

So, next step now is running ng serve to check if everything is ok with the code. Don’t forget to verify https://update.angular.io/ for all beaking changes.

Even though we were able to update RxJS code since Angular v5 (with RxJS v5) to use the pipeble operators, in the projects I did the upgrade to v6, I forgot to change a few places. To help us with this task, we can install rxjs-tslint to help us removing all deprecated RxJS code.

npm install -g rxjs-tslint
rxjs-5-to-6-migrate -p src/tsconfig.app.json

As a quick summary regarding the imports:

import { Subject } from 'rxjs/Subject';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { of } from 'rxjs/observable/of;'

to:

import { BehaviorSubject, Subject, Observable, of } from 'rxjs';

Or, if you were not using RxJS pipeble operators yet:

import 'rxjs/add/observable/of';    
import 'rxjs/add/operator/catch';   
import 'rxjs/add/operator/do';  
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/mergeMap';    
import 'rxjs/add/operator/switchMap';

to

import { of } from 'rxjs';
import { map, switchMap, catchError, mergeMap } from 'rxjs/operators';

The following operators were renamed as well:

do -> tap
catch -> catchError
switch -> switchAll
finally -> finalize

And in our code, we can start using the pipeble operators.

From:

this.http.get('url')
  .do(console.log)
  .map(results => results.data)
  .subscribe(results => {
    console.log('Results', results);
  });

To:

this.http.get('url')
  .pipe(
    tap(console.log), // old 'do' operator
    map(results => results.data)
  )
  .subscribe(results => {
    console.log('Results', results);
  });

After updating your RxJS code, you might still get errors regarding RxJS from third-party dependencies. To solve this, install rxjs-compat and once the dependencies have upgraded their code as well, you can remove this package from your project.

npm install --save rxjs-compat

5: Simplifying Dependency Injection for Core Services

A new feature introduced in Angular v6 is called "tree-shakable providers". This means we no longer need to declare services in a module by using the property providedIn, and this will allow the services to be tree-shakable, meaning if they are not being used, they will not be part of the prod bundle.

import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class MyCoreService { }

I applied this feature in all core services (global scope) of my projects, but I’m still using non tree-shakable providers with services that do not have global scope.

This allowed to clean up the providers section from CoreModule.

6: Updating Angular Material (optional)

If you are using Angular Material in your project, don’t forget to run ng update @angular/material to update the material dependencies.

A breaking change from v5 to v6 is how we import the Material modules in our project:

From:

import {
  MdToolbarModule,
  MdIconModule,
  MdButtonModule,
  MdMenuModule,
  MdCardModule
} from '@angular/material';

To:

import { MatToolbarModule } from '@angular/material/toolbar';
import { MatIconModule } from '@angular/material/icon';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatCardModule } from '@angular/material/card';

Now each module has its own package. This is also one of the reasons I like to create a separate module for thrid party imports as already explained in this article. It makes much easier to fix imports!

Some other things… I do have some projects that were created since Angular v2, and after every major version update, I usually just updated package.json and fixed the breaking changes in the code and that was ok.

Since there were some project structure changes in Angular CLI v6, I also decided to migrate a project by creating a brand new project with CLI 6 and copying the src folder from the old project to the new project. Below are some of the most impacted changes.

The major difference that had some impact on the code is the baseUrl: './' from tsconfig.json. With projects created with CLI 1.x (for Angular v4 and v5), this configuration is not there by default (but inside src/tsconfig.ap.json). Moving baseUrl to the root tsconfig.json had an impact on custom paths declared in tsconfig.json and also on the path for lazy loading modules.

Before - custom path in tsconfig.json:

paths: {
  "@env/*": ["environments/*"]
}

After (single project created with CLI v6):

paths: {
  "@env/*": ["src/environments/*"]
}

And the lazy loading modules need to be declared using the relative path:

Before:

{ path: 'home', loadChildren: 'app/home/home.module#HomeModule' }

After:

{ path: 'home', loadChildren: './home/home.module#HomeModule' }

If you have nested modules, you also need to update them to use relative paths:

Before (module1-routing.module.ts):

{ path: 'foo', loadChildren: 'app/module1/module2/module2.module#Module2Module' }

After (module1-routing.module.ts):

{ path: 'foo', loadChildren: './module2/module2.module#Module2Module' }

There were a few changes in the CLI v6 commands as well. As the majority of my professional applications use Java in the backend, the output folder (dist) from ng build is configured to a different path. Until CLI 1.x, there was a flag (output-path -op) that could be used in the ng build command (ng build -op ../other/path). With CLI v6, if you need to use a different output path, you need to update angular.json and remove the -op flag from ng build:

"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      "outputPath": "../other/path",
      ...
    }
  }
} 

这篇关于将 angular 4 项目升级到 angular 6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆