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

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

问题描述

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

我已按照 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 

但是这些步骤是要升级到7号角而不是6号角

运行ng update命令后的结果屏幕截图:

我错过了任何步骤,如何升级到6号角而不是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@angular/core和其他所需的其他软件包(rxjs, @angular/material)运行ng update命令:

ng update @angular/cli
ng update @angular/core
ng update @angular/material
ng update 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-tslint
rxjs-5-to-6-migrate -p src/tsconfig.app.json

作为有关进口的快速摘要:

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

收件人:

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

或者,如果您尚未使用RxJS管道运算符:

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';

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

以下运算符也被重命名:

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

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

发件人:

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

收件人:

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

更新RxJS代码后,您仍可能会从第三方依赖项中获取有关RxJS的错误.要解决此问题,请安装rxjs-compat,并且依赖项也已升级了它们的代码后,您可以从项目中删除此软件包.

npm install --save rxjs-compat

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

Angular v6中引入的一项新功能称为可树状提供程序".这意味着我们不再需要使用属性providedIn在模块中声明服务,这将使这些服务可树状摇动,这意味着如果不使用它们,它们将不会成为prod捆绑包的一部分.

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

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

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

这允许从CoreModule清除提供程序部分.

6:更新Angular材质(可选)

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

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

发件人:

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

收件人:

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';

现在每个模块都有自己的软件包.这也是我喜欢为第三方导入创建单独的模块的原因之一,如本文所述.这样可以更轻松地修复导入!

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

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

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

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

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

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

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

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

之前:

{ 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,在ng build命令(ng build -op ../other/path)中都有一个标志(output-path -op).在CLI v6中,如果需要使用其他输出路径,则需要更新angular.json并从ng build中删除-op标志:

"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:browser",
    "options": {
      "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",
      ...
    }
  }
} 

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

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