TypeScript工具迁移技能Skill typescript-tooling-migration

这个技能提供了一个指南,用于在Phoenix monorepo中迁移或升级TypeScript工具,包括工具替换、版本升级和依赖管理。关键词:TypeScript、工具迁移、前端开发、monorepo、CI/CD、React、oxlint、oxfmt。

前端开发 0 次安装 0 次浏览 更新于 3/10/2026

name: typescript-tooling-migration description: 在Phoenix monorepo中迁移或升级TypeScript工具的指南。覆盖核心依赖升级(TypeScript、React)、工具切换(linter、formatter、bundler),以及管理app/js/目录中的破坏性变更。 license: Apache-2.0 metadata: author: oss@arize.com version: “1.0.0” languages: TypeScript internal: true

TypeScript 工具迁移

在Phoenix monorepo中迁移或升级TypeScript工具的指南。此技能覆盖核心依赖升级(TypeScript、React)、工具切换(linter、formatter、bundler),以及管理app/js/目录中的破坏性变更。

Monorepo 结构

Phoenix有两个TypeScript项目目录,必须保持同步:

目录 目的 包管理器
app/ React/TypeScript前端(主要Phoenix UI) pnpm
js/ TypeScript包monorepo(phoenix-client、phoenix-evals等) pnpm(工作区)

共享依赖

两个目录应使用相同版本的共享工具:

工具 同步强制 配置位置
pnpm CI检查 package.jsonpackageManager
TypeScript CI检查 package.jsondevDependencies
oxlint CI检查 package.jsondevDependencies
oxfmt CI检查 package.jsondevDependencies

配置文件位置

配置 位置 目的
.oxlintrc.json 根目录 + app/ + js/ Linter配置(嵌套继承)
.oxfmtrc.jsonc 根目录 Formatter配置(共享)
tsconfig.json app/js/ TypeScript配置
vite.config.ts app/ 构建/开发服务器配置
relay.config.js app/ GraphQL/Relay配置

迁移类型

类型1:工具替换(例如,ESLint → oxlint)

完全替换一个工具为另一个。

工作流:

  1. 研究新工具的迁移指南
  2. 与旧工具一起安装新工具
  3. 创建新配置,验证其工作
  4. 更新包脚本
  5. 更新预提交钩子
  6. 移除旧工具和配置
  7. 更新文档

类型2:主要版本升级(例如,TypeScript 5 → 6)

将工具升级到带有破坏性变更的新主要版本。

工作流:

  1. 阅读变更日志/迁移指南中的破坏性变更
  2. 检查依赖包的兼容性
  3. 在分支中升级,修复破坏性变更
  4. 运行完整测试套件
  5. 更新任何已弃用的配置选项
  6. 如果API更改,更新文档

类型3:依赖升级(例如,React 18 → 19)

升级影响应用程序代码的核心依赖。

工作流:

  1. 检查兼容性矩阵(React + React DOM + types)
  2. 回顾破坏性变更和新特性
  3. 一起升级依赖
  4. 在应用程序代码中修复破坏性变更
  5. 更新任何已弃用的模式
  6. 运行E2E测试以验证功能

迁移工作流

阶段1:研究与规划

  1. 阅读官方迁移指南 - 大多数工具发布升级指南
  2. 检查GitHub问题 - 查找已知迁移问题
  3. 识别范围:
    • 哪些目录受影响(app/js/,或两者)
    • 哪些配置文件需要更改
    • 添加/移除/升级哪些依赖
    • 需要哪些代码更改
  4. 回顾当前配置 - 更改前理解现有设置
  5. 检查依赖包 - 确保依赖树中的兼容性

阶段2:创建迁移分支

git checkout -b chore/migrate-<tool>-to-<version>
# 或
git checkout -b chore/upgrade-<tool>-<version>

阶段3:安装/升级依赖

# 对于app/(标准项目)
cd app && pnpm add -D <package>@<version>

# 对于js/(工作区根目录)
cd js && pnpm add -D -w <package>@<version>

# 对于升级现有依赖
cd app && pnpm update <package>@<version>

提示: 在迁移验证前保持旧工具安装,对于工具替换。

阶段4:更新配置

对于工具替换 - 创建新配置:

Phoenix使用嵌套配置与继承,尽可能:

phoenix/
├── .<tool>rc.json           # 共享基础配置
├── app/
│   └── .<tool>rc.json       # 扩展基础,添加React特定选项
└── js/
    └── .<tool>rc.json       # 扩展基础,添加Node特定选项

配置继承模式:

{
  "$schema": "./node_modules/<tool>/configuration_schema.json",
  "extends": ["../.<tool>rc.json"]
}

对于版本升级 - 更新现有配置:

  1. 在变更日志中检查已弃用的选项
  2. 更新或移除已弃用的设置
  3. 添加任何新要求的设置

阶段5:修复破坏性变更

代码更改:

  • 修复更严格检查导致的类型错误
  • 更新已弃用的API使用
  • 适应新语法要求

配置更改:

  • 更新已弃用的配置选项
  • 调整更改后的默认值

提示: 使用工具自身的CLI识别问题:

pnpm run typecheck  # TypeScript错误
pnpm run lint       # Linter错误
pnpm run build      # 构建错误

阶段6:更新包脚本

如果脚本调用更改,更新app/package.jsonjs/package.json

{
  "scripts": {
    "lint": "<new-command>",
    "typecheck": "<new-command>"
  }
}

阶段7:更新预提交钩子

如果工具用于预提交,编辑.pre-commit-config.yaml

  1. 移除旧工具的钩子(对于替换)
  2. 更新或添加新钩子:
- id: <tool>-app
  name: <tool> (app)
  entry: pnpm --dir app run <script>
  language: system
  files: ^app/.*\.[jt]sx?$
  pass_filenames: false
- id: <tool>-js
  name: <tool> (js)
  entry: pnpm --dir js run <script>
  language: system
  files: ^js/.*\.[jt]sx?$
  pass_filenames: false

阶段8:更新编辑器设置

  1. 如果扩展更改,更新.vscode/extensions.json
  2. DEVELOPMENT.md中记录任何路径/二进制设置:
{
  "<extension>.path.<binary>": "app/node_modules/<package>/bin/<binary>"
}

注意:.vscode/settings.json被git忽略 - 在DEVELOPMENT.md中记录设置。

阶段9:移除旧工具(对于替换)

# 移除旧依赖
cd app && pnpm remove <old-tool> <old-plugins>
cd js && pnpm remove -w <old-tool> <old-plugins>

# 删除旧配置文件
rm app/<old-config> js/<old-config>

阶段10:测试与验证

# 类型检查
cd app && pnpm run typecheck
cd js && pnpm run typecheck

# Linting
cd app && pnpm run lint
cd js && pnpm run lint

# 格式化
cd app && pnpm run fmt:check
cd js && pnpm run fmt:check

# 单元测试
cd app && pnpm test
cd js && pnpm run -r test

# 构建
cd app && pnpm run build
cd js && pnpm run -r build

# E2E测试(对于重大更改)
cd app && pnpm run test:e2e

# 预提交钩子
pre-commit run --all-files

阶段11:更新文档

要检查和更新的文件:

文件 更新内容
AGENTS.md 工具版本、命令、风格约定
DEVELOPMENT.md 设置说明、VS Code设置
app/README.md 工具引用、测试命令
.cursor/rules/typescript-packages/RULE.md 命令、工作流说明
.claude/settings.json PostToolUse钩子
CHANGELOG.md 记录重大工具更改

阶段12:添加/更新版本同步检查

对于共享依赖,确保.github/workflows/package-version-check.yml强制一致性:

- name: 检查 <tool> 版本一致性
  run: |
    APP_VERSION=$(jq -r '.devDependencies.<tool> // empty' app/package.json)
    JS_VERSION=$(jq -r '.devDependencies.<tool> // empty' js/package.json)

    echo "app/package.json: <tool>@$APP_VERSION"
    echo "js/package.json: <tool>@$JS_VERSION"

    if [ -z "$APP_VERSION" ]; then
      echo "::error::app/package.json 缺少 <tool> 在 devDependencies 中"
      exit 1
    fi

    if [ -z "$JS_VERSION" ]; then
      echo "::error::js/package.json 缺少 <tool> 在 devDependencies 中"
      exit 1
    fi

    if [ "$APP_VERSION" != "$JS_VERSION" ]; then
      echo "::error::<tool> 版本不匹配!"
      exit 1
    fi

    echo "<tool> 版本一致: $APP_VERSION"

关键原则

保持目录同步

升级共享工具时,始终同时升级app/js/。版本漂移会导致微妙错误和CI失败。

性能重要

  • 测量升级前后的构建时间、lint时间、测试时间
  • 一些兼容层(如linter的JS插件)添加显著开销
  • 优先选择原生实现而非兼容垫片

向后兼容性

  • 许多工具支持遗留配置格式(例如,oxlint支持eslint-disable注释)
  • 除非有明确好处,不要大规模更新工作代码
  • 弃用警告是信息性的 - 修复它们但不要阻塞于它们

配置位置策略

场景 方法
两个目录的相同配置 单个根配置
共享基础 + 目录特定覆盖 根配置 + 嵌套配置使用extends
每个目录的完全不同配置 单独配置(无继承)

范围外目录

这些目录有自己的工具,不应包含在迁移中:

  • scripts/docker/devops/oidc-server/ - 单独的OIDC测试服务器
  • scripts/mock-llm-server/ - 单独的模拟服务器
  • internal_docs/ - 内部文档实用程序

故障排除

TypeScript 升级问题

更严格的类型检查: 新TypeScript版本通常添加更严格的检查。通过以下方式修复错误:

  1. 添加显式类型注解
  2. 在适当的地方使用类型断言
  3. 如果需要,更新tsconfig.json临时放宽检查

依赖类型不匹配: 确保@types/*包与新TS版本兼容。

升级后构建失败

  1. 清除缓存:rm -rf node_modules/.cache app/dist js/**/dist
  2. 重新安装:pnpm install
  3. 重新构建:pnpm run build

配置未找到

  • 检查$schema路径相对于配置文件位置
  • 对于嵌套配置,验证extends路径(例如,"../.toolrc.json"

编辑器未使用更新后的工具

  1. 确保扩展是最新的
  2. 在VS Code设置中设置显式二进制路径
  3. 重新加载VS Code窗口(Cmd+Shift+P → “重新加载窗口”)

预提交钩子失败

  • 在两个目录中运行pnpm install
  • 验证package.json中的脚本名称与钩子条目匹配
  • 手动测试脚本:pnpm --dir app run <script>

CI 失败但本地通过

  • 检查Node版本匹配CI(见.nvmrc
  • 确保锁文件已提交(pnpm-lock.yaml
  • 在本地运行--frozen-lockfile以匹配CI行为

CI 工作流

TypeScript工具的相关CI文件:

工作流 目的
.github/workflows/typescript-CI.yml app/ 类型检查、lint、测试
.github/workflows/typescript-packages-CI.yml js/ 构建、测试、lint
.github/workflows/package-version-check.yml 版本同步强制
.github/workflows/playwright.yaml E2E测试

参考资料

一般

当前工具