Angular升级与迁移指南

Angular团队每6个月发布一个主要版本,包含新功能、改进和重大变更。本章将指导你如何安全地升级Angular应用,从旧版本迁移到最新版本。

版本发布周期: 每6个月一个主要版本 每2个月一个小版本 每1-2周一个补丁版本

1. 升级策略与路线图

4

Angular 4-5(旧版)

建议直接升级到Angular 8+,再逐步升级到最新版

6-8

Angular 6-8(过渡版)

可升级到Angular 12+,然后到最新版

9

Angular 9(IVY引擎)

重大变更:引入IVY编译和渲染引擎

10-12

Angular 10-12(现代版)

相对平滑的升级路径

13

Angular 13+(最新)

移除View Engine,仅支持IVY

14+

Angular 14+(当前推荐)

稳定版本,支持最新功能

2. 升级前准备

备份项目

确保有完整的项目备份,包括源代码和node_modules

# 使用Git创建备份分支
git checkout -b backup-before-upgrade
git add .
git commit -m "备份: 升级前状态"
更新Node.js

确保Node.js版本符合Angular要求

Angular版本 Node.js版本 TypeScript版本
Angular 13+ 14.20+ / 16.13+ / 18.10+ 4.2+
Angular 12 12.14+ / 14.15+ 4.2+
Angular 11 10.13+ / 12.11+ 4.0+
Angular 10 10.13+ / 12.11+ 3.9+
检查第三方依赖

确保所有第三方库都支持目标Angular版本

# 检查过时的依赖
npm outdated

# 检查与Angular的兼容性
npm ls @angular/core

3. 使用ng update自动化升级

ng update 命令

Angular CLI提供的自动化升级工具

ng update [包名] [选项]
选项 说明 示例
--force 强制更新,忽略警告 --force
--next 更新到下一个预发布版本 --next
--all 更新所有包 --all
--migrate-only 只运行迁移,不更新包 --migrate-only
--from 指定从哪个版本迁移 --from=10.0.0
--to 指定迁移到哪个版本 --to=13.0.0
推荐升级路径
# 一步式升级(推荐)
ng update @angular/cli @angular/core

# 逐步升级
ng update @angular/cli@13 @angular/core@13
ng update @angular/cli@14 @angular/core@14
ng update @angular/cli@15 @angular/core@15
跨大版本升级
# 从Angular 8升级到13
ng update @angular/cli@9 @angular/core@9
ng update @angular/cli@10 @angular/core@10
ng update @angular/cli@11 @angular/core@11
ng update @angular/cli@12 @angular/core@12
ng update @angular/cli@13 @angular/core@13
危险操作
# 不要这样做!
ng update --all --force
# 可能破坏项目

4. 重大变更处理

Angular 9+:IVY引擎

变更内容: 引入了新的编译和渲染引擎IVY
// 升级后需检查
import { Component } from '@angular/core';

// 确保没有使用已弃用的API
@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  // 不再支持`entryComponents`
})
export class ExampleComponent {}

Angular 13:移除View Engine

重要: 完全移除了旧的View Engine,仅支持IVY
// angular.json配置变化
{
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "options": {
            // 不再需要这个配置
            // "aot": true // 默认启用且不可禁用
          }
        }
      }
    }
  }
}

Angular 14:严格类型表单

// FormsModule的重大变更
import { FormControl, FormGroup } from '@angular/forms';

// 旧方式(松散类型)
const form = new FormGroup({
  name: new FormControl(''),
  age: new FormControl(0)
});

// 新方式(严格类型)
const form = new FormGroup<{
  name: FormControl;
  age: FormControl;
}>({
  name: new FormControl(''),
  age: new FormControl(0)
});

Angular 15:独立组件

// 新的独立组件API
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';

@Component({
  selector: 'app-standalone',
  standalone: true, // 标记为独立组件
  imports: [CommonModule, RouterModule], // 显式导入依赖
  templateUrl: './standalone.component.html',
})
export class StandaloneComponent {}

5. 常见升级问题与解决方案

# 清理缓存并重新安装依赖
rm -rf node_modules package-lock.json
npm cache clean --force
npm install

# 或者使用yarn
yarn cache clean
yarn install

// 更新类型定义
// 1. 检查第三方库的@types包
npm install @types/库名@latest

// 2. 更新Angular类型
npm install @angular/core@latest @angular/common@latest

// 3. 如有需要,临时禁用严格模式
// tsconfig.json
{
  "compilerOptions": {
    "strict": false // 临时关闭
  }
}

// IVY中样式封装的变更
@Component({
  selector: 'app-example',
  templateUrl: './example.component.html',
  styleUrls: ['./example.component.scss'],
  // 尝试不同的封装模式
  encapsulation: ViewEncapsulation.None
  // 或者
  encapsulation: ViewEncapsulation.ShadowDom
})

// 或者全局修复
// angular.json
{
  "projects": {
    "my-app": {
      "architect": {
        "build": {
          "options": {
            "styles": [
              "src/styles.scss" // 确保全局样式正确引入
            ]
          }
        }
      }
    }
  }
}

6. AngularJS到Angular迁移

ngUpgrade - 混合模式迁移

允许AngularJS和Angular在同一个应用中运行

// 安装升级模块
import { UpgradeModule } from '@angular/upgrade/static';

@NgModule({
  imports: [
    BrowserModule,
    UpgradeModule
  ]
})
export class AppModule {
  constructor(private upgrade: UpgradeModule) {}

  ngDoBootstrap() {
    this.upgrade.bootstrap(document.body, ['angularjs-app'], { strictDi: true });
  }
}

// 降级Angular组件供AngularJS使用
import { downgradeComponent } from '@angular/upgrade/static';

angular.module('angularjs-app')
  .directive('appAngularComponent',
    downgradeComponent({ component: AngularComponent }) as angular.IDirectiveFactory
  );
迁移策略
  • 大爆炸迁移:一次性重写整个应用
  • 逐步迁移:逐个功能迁移(推荐)
  • 混合模式:同时运行两个框架
  • 微前端:将应用拆分为独立模块
迁移工具
  • ngUpgrade:官方升级库
  • angular-cli-ghpages:部署工具
  • codelyzer:代码质量检查
  • angular-eslint:ESLint配置

7. 升级检查清单

升级前检查
  • ✅ 项目已备份
  • ✅ Node.js版本符合要求
  • ✅ TypeScript版本兼容
  • ✅ 第三方库支持目标版本
  • ✅ 测试套件完整
升级中操作
  • ✅ 使用ng update按顺序升级
  • ✅ 逐个解决编译错误
  • ✅ 运行自动化测试
  • ✅ 检查控制台警告
  • ✅ 验证路由和导航
升级后验证
  • ✅ 应用能正常启动
  • ✅ 所有功能正常工作
  • ✅ 性能没有下降
  • ✅ 打包大小正常
  • ✅ 文档已更新

8. 性能影响与优化

正面影响
  • 更小的包大小:IVY减少30-40%
  • 更快的编译:增量编译优化
  • 更好的Tree Shaking:更有效的死代码消除
  • 改进的运行时性能:更快的变更检测
潜在问题
  • 初始构建变慢:需要重新编译
  • 内存使用增加:IVY编译需要更多内存
  • 第三方库兼容性:可能需要更新
  • 学习曲线:新API需要适应
优化建议
  • 使用生产构建:ng build --prod
  • 启用AOT:默认启用
  • 代码分割:懒加载模块
  • 更新依赖:使用最新稳定版
升级最佳实践
  • 逐步升级:一次升级一个主要版本
  • 充分测试:升级后运行完整的测试套件
  • 关注日志:仔细阅读ng update的输出
  • 利用工具:使用Angular DevTools分析性能
  • 团队协作:确保所有开发者使用相同版本
  • 文档更新:及时更新项目文档
常见陷阱
  • 忽略peerDependencies警告:可能导致运行时错误
  • 跳过测试:可能导致未发现的回归问题
  • 强制更新:可能破坏项目结构
  • 不及时更新:落后太多版本会增加升级难度
  • 忽略弃用警告:未来版本可能完全移除功能

9. 资源与工具

实用工具
  • ngx-upgrade:社区升级工具
  • codemod:自动代码转换工具
  • lighthouse:性能检测工具
  • webpack-bundle-analyzer:包大小分析
获取帮助

遇到问题? 参考以下资源:
- Stack Overflow: angular标签
- GitHub Issues: Angular仓库
- Angular Discord: 社区讨论