问题修复
升级框架/依赖主版本并处理破坏性变更时,用兼容性分析…
适用于框架或库的大版本升级、安全漏洞依赖更新、依赖冲突解决、增量升级路径规划及自动化依赖更新配置。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
升级框架/依赖主版本并处理破坏性变更时,通用
解决思路
- 先复习语义化版本:MAJOR.MINOR.PATCH;MAJOR 为破坏性变更,MINOR/PATCH 向后兼容;^2.3.1 允许 minor 更新,~2.3.1 允许 patch 更新,2.3.1 为精确版本。
- 审计依赖:npm outdated、npm audit、npm audit fix。
- Yarn 审计:yarn outdated、yarn audit。
- 检查主版本更新:npx npm-check-updates;写入 package.json 用 npx npm-check-updates -u。
- 分析依赖树:npm ls package-name、yarn why package-name。
- 查找重复包:npm dedupe、yarn dedupe。
- 可视化依赖:npx madge --image graph.png src/。
- 建立兼容性矩阵:创建 compatibility-matrix.js,在 compatibilityMatrix 中为框架各主版本定义对应依赖版本范围。
- 编写 checkCompatibility(packages) 校验包版本是否满足兼容矩阵。
- 规划阶段:用 npm list --depth=0 识别当前版本。
- 阅读 CHANGELOG.md 和 MIGRATION.md 检查破坏性变更。
- 创建升级计划:将升级顺序写入 UPGRADE_PLAN.md,例如 TypeScript、React、React Router、测试库、构建工具。
- 增量更新阶段:不要一次性升级所有依赖。
- 先更新 TypeScript:npm install typescript@latest,然后运行 npm run test 和 npm run build。
- 再更新 React:一次只升一个大版本,如 npm install react@17 react-dom@17,然后运行 npm run test。
- 继续更新其他包,如 npm install react-router-dom@6,每次升级后测试。
- 验证阶段:编写 tests/compatibility.test.js,检查 react 与 react-dom 版本一致。
- 在兼容性测试中检查 peer dependency 警告,例如运行 npm ls 并确认无警告。
- 识别破坏性变更:直接拉取 changelog,如 curl https://raw.githubusercontent.com/facebook/react/master/CHANGELOG.md。
- 用 codemod 自动修复:npx jscodeshift -t <transform-url> <path>。
- 示例:重命名 unsafe lifecycle 方法:npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js src/。
- TypeScript 文件加 --parser=tsx:npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js --parser=tsx src/。
- 用 --dry 预览 codemod 变更:npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js --dry src/。
- 自定义迁移脚本:创建 migration-script.js,用 glob 遍历 src/**/*.tsx,读取文件并替换旧 API 与新 API,更新 import,再写回文件。
- 单元测试:升级前后运行 npm run test;需要时更新测试工具,如 npm install @testing-library/react@latest。
- 集成测试:写 tests/integration/app.test.js,覆盖 App 渲染不崩溃和导航交互。
- 视觉回归测试:写 visual-regression.test.js,用 toMatchSnapshot 对比快照。
- E2E 测试:写 cypress/e2e/app.cy.js,覆盖访问 /、点击登录、输入 email、提交、校验跳转到 /dashboard 等用户流程。
- 自动化依赖更新 Renovate:创建 renovate.json,extends config:base;minor/patch 自动合并,major 不自动合并并加 major-update 标签;设置 schedule 为 before 3am on Monday,timezone 为 America/New_York。
- 自动化依赖更新 Dependabot:创建 .github/dependabot.yml,version 2;npm 根目录每周检查;open-pull-requests-limit 5;reviewers team-leads;commit-message prefix chore、include scope。
- 制定回滚计划:rollback.sh 中先 git stash,创建 upgrade-branch,安装 package@latest,运行 npm run test;成功则提交 package.json 和 package-lock.json,失败则切回 main、删除分支并用 npm install 从 lock 文件恢复。
- 锁文件管理:npm 用 npm install --package-lock-only 只更新锁文件,npm ci 从锁文件干净安装。
- Yarn 锁文件管理:yarn install --frozen-lockfile 用于 CI,yarn upgrade-interactive 交互式升级。
- peer dependency 解决:npm 7+ 严格 peer 依赖时,用 npm install --legacy-peer-deps 忽略 peer deps;npm 8+ 用 npm install --force 覆盖 peer deps。
- 工作区升级:npm install --workspaces 更新所有 workspace 包;npm install package@latest --workspace=packages/app 更新指定工作区。
适用边界 · 注意事项
- 没有可运行的测试套件、没有 lock 文件或无法回滚时,不要直接在生产分支做大规模升级。
- 依赖间 peer dependency 冲突严重时,不要用 --force/--legacy-peer-deps 长期掩盖,应先解决兼容性或评估替换。
- 当升级需要重写业务代码且无迁移指南/兼容矩阵时,不适合按常规增量升级,需先做 PoC 或重写评估。