angular-modernization

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Angular Modernization

Angular代码现代化

Transforms legacy Angular components to modern architecture using a two-step approach:
  1. Automated migrations - Angular CLI schematics for standalone, control flow, and signals
  2. Bitwarden patterns - ADR compliance, OnPush change detection, proper visibility, thin components
将遗留Angular组件转换为现代架构,采用两步法:
  1. 自动迁移 - 用于standalone、控制流和signals的Angular CLI schematics
  2. Bitwarden模式 - 符合ADR规范、OnPush变更检测、正确的可见性设置、轻量组件

Workflow

工作流程

Step 1: Run Angular CLI Migrations

步骤1:运行Angular CLI迁移

⚠️ CRITICAL: ALWAYS use Angular CLI migrations when available. DO NOT manually migrate features that have CLI schematics.
Angular provides automated schematics that handle edge cases, update tests, and ensure correctness. Manual migration should ONLY be used for patterns not covered by CLI tools.
IMPORTANT:
  • Always run the commands using
    npx ng
    .
  • All the commands must be run on directories and NOT files. Use the
    --path
    option to target directories.
  • Run migrations in order (some depend on others)
⚠️ 重要提示:只要有可用的Angular CLI迁移,就必须使用它。请勿手动迁移有CLI schematics支持的功能。
Angular提供的自动化schematics可以处理边缘情况、更新测试并确保正确性。仅当CLI工具未覆盖相关模式时,才应使用手动迁移。
注意事项:
  • 始终使用
    npx ng
    运行命令。
  • 所有命令必须在目录而非文件上运行。使用
    --path
    选项指定目标目录。
  • 按顺序运行迁移(部分迁移依赖于其他迁移)

1. Standalone Components

1. Standalone组件

bash
npx ng generate @angular/core:standalone --path=<directory> --mode=convert-to-standalone
NgModule-based → standalone architecture
bash
npx ng generate @angular/core:standalone --path=<directory> --mode=convert-to-standalone
基于NgModule的架构 → standalone架构

2. Control Flow Syntax

2. 控制流语法

bash
npx ng generate @angular/core:control-flow
*ngIf
,
*ngFor
,
*ngSwitch
@if
,
@for
,
@switch
bash
npx ng generate @angular/core:control-flow
*ngIf
,
*ngFor
,
*ngSwitch
@if
,
@for
,
@switch

3. Signal Inputs

3. Signal输入

bash
npx ng generate @angular/core:signal-input-migration
@Input()
→ signal inputs
bash
npx ng generate @angular/core:signal-input-migration
@Input()
→ signal输入

4. Signal Outputs

4. Signal输出

bash
npx ng generate @angular/core:output-migration
@Output()
→ signal outputs
bash
npx ng generate @angular/core:output-migration
@Output()
→ signal输出

5. Signal Queries

5. Signal查询

bash
npx ng generate @angular/core:signal-queries-migration
@ViewChild
,
@ContentChild
, etc. → signal queries
bash
npx ng generate @angular/core:signal-queries-migration
@ViewChild
,
@ContentChild
, etc. → signal查询

6. inject() Function

6. inject()函数

bash
npx ng generate @angular/core:inject-migration
Constructor injection →
inject()
function
bash
npx ng generate @angular/core:inject-migration
构造函数注入 →
inject()
函数

7. Self-Closing Tag

7. 自闭合标签

bash
npx ng generate @angular/core:self-closing-tag
Updates templates to self-closing syntax
bash
npx ng generate @angular/core:self-closing-tag
将模板更新为自闭合语法

8. Unused Imports

8. 未使用的导入

bash
npx ng generate @angular/core:unused-imports
Removes unused imports
bash
npx ng generate @angular/core:unused-imports
移除未使用的导入

Step 2: Apply Bitwarden Patterns

步骤2:应用Bitwarden模式

See migration-patterns.md for detailed examples.
  1. Add OnPush change detection
  2. Apply visibility modifiers (
    protected
    for template access,
    private
    for internal)
  3. Convert local component state to signals
  4. Keep service observables (don't convert to signals)
  5. Extract business logic to services
  6. Organize class members correctly
  7. Update tests for standalone
详见migration-patterns.md中的详细示例。
  1. 添加OnPush变更检测
  2. 应用可见性修饰符(模板访问使用
    protected
    ,内部实现使用
    private
  3. 将组件本地状态转换为signals
  4. 保留服务的observables(不要转换为signals)
  5. 将业务逻辑提取到服务中
  6. 正确组织类成员
  7. 更新测试以适配standalone架构

Step 3: Validate

步骤3:验证

  • Fix linting and formatting using
    npm run lint:fix
  • Run tests using
    npm run test
If any errors occur, fix them accordingly.
  • 使用
    npm run lint:fix
    修复代码检查和格式问题
  • 使用
    npm run test
    运行测试
如果出现任何错误,相应地修复它们。

Key Decisions

关键决策

Signals vs Observables

Signals vs Observables

  • Signals - Component-local state only (ADR-0027)
  • Observables - Service state and cross-component communication (ADR-0003)
  • Use
    toSignal()
    to bridge observables into signal-based components
  • Signals - 仅用于组件本地状态(ADR-0027)
  • Observables - 服务状态和跨组件通信(ADR-0003)
  • 使用
    toSignal()
    将observables桥接到基于signal的组件中

Visibility

可见性

  • protected
    - Template-accessible members
  • private
    - Internal implementation
  • protected
    - 模板可访问的成员
  • private
    - 内部实现

Other Rules

其他规则

  • Always add OnPush change detection
  • No TypeScript enums (use const objects with type aliases per ADR-0025)
  • No code regions (refactor instead)
  • Thin components (business logic in services)
  • 始终添加OnPush变更检测
  • 不使用TypeScript枚举(根据ADR-0025,使用带类型别名的const对象)
  • 不使用代码区域(而是重构代码)
  • 轻量组件(业务逻辑放在服务中)

Validation Checklist

验证检查清单

Before completing migration:
  • OnPush change detection added
  • Visibility modifiers applied (
    protected
    /
    private
    )
  • Signals for component state, observables for service state
  • Class members organized (see migration-patterns.md)
  • Tests updated and passing
  • No new TypeScript enums
  • No code regions
完成迁移前:
  • 已添加OnPush变更检测
  • 已应用可见性修饰符(
    protected
    /
    private
  • 组件状态使用signals,服务状态使用observables
  • 类成员已正确组织(详见migration-patterns.md
  • 测试已更新并通过
  • 未新增TypeScript枚举
  • 无代码区域

References

参考资料

Bitwarden ADRs

Bitwarden ADR文档

Angular Resources

Angular资源