ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Nx 23.1.0 TypeScript 6 迁移指南:用 ignoreDeprecations 与默认值固定让存量工作区平稳编译

Nx 23.1.0 TypeScript 6 迁移指南:用 ignoreDeprecations 与默认值固定让存量工作区平稳编译 Nx 23.1.0 TypeScript 6 迁移指南用 ignoreDeprecations 与默认值固定让存量工作区平稳编译【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nxTypeScript 6 将多项长期废弃的编译选项升级为硬错误并翻转了若干选项的默认值直接升级会让大量存量 Nx 工作区立刻编译失败。本文基于 Nx 仓库中的官方迁移文档 add-ignore-deprecations-for-ts6.md结合 迁移源码 与其 测试用例完整讲解 Nx 23.1.0 提供的23-1-0-add-ignore-deprecations-for-ts6自动迁移它如何写入ignoreDeprecations: 6.0、如何为四条被翻转的默认值做固定pin、又如何在不改动共享 base 配置的前提下通过extends继承语义精准落笔。读完你将掌握 TypeScript 6 下这些破坏性变化的具体表现以及 Nx 迁移机制如何在不改变项目语义的前提下保住编译与运行行为。TypeScript 6 带来的四类破坏性变化要理解这次迁移的价值先看清 TypeScript 6 相对 TypeScript 5 到底改了什么。迁移文档与源码DEFAULT_PRESERVING_PINS常量的注释把破坏点归结为四类这也是迁移需要固定的四条默认值编译选项TypeScript 5 行为TypeScript 6 行为不处理的结果strict未设置时视为false未设置时视为true原本非严格模式的项目突然进入严格模式出现大量类型错误noUncheckedSideEffectImports默认false默认true裸副作用导入如import ./styles.css若没有对应的 ambient 模块声明会变成硬错误TS2882types未设置时自动加载全部types包未设置时不再自动加载依赖隐式加载全部 types的配置典型如 ts-node 编译jest.config.ts时依赖types/node会丢失类型esModuleInterop默认false默认翻转为trueimport * as x from cjs绑定到不可调用的命名空间对象调用或new该导入会在运行时失败其中esModuleInterop: false本身在 TypeScript 6 里就是一个废弃值将在 TypeScript 7 中被移除所以它既要被固定下来保持旧行为又要靠ignoreDeprecations压制它触发的废弃告警——迁移把这两件事放在同一次运行里完成。废弃值升级为硬错误的完整清单迁移源码中的hasDeprecatedOption函数add-ignore-deprecations-for-ts6.ts给出了被判定为TypeScript 6 废弃值的完整清单与文档列出的示例一一对应moduleResolution设置为node/node10/classic设置了baseUrltarget设置为es5esModuleInterop: false设置了outFilemodule设置为amd/umd/system/nonealwaysStrict: falseallowSyntheticDefaultImports: false设置了downlevelIteration无论真假。这些值在 TypeScript 5.8 上还能静默编译到了 TypeScript 6.0 就会变成TS5101/TS5107一类的硬废弃错误。测试用例 detectedCases 逐一验证了这些值的检测逻辑。迁移的整体设计与执行时机23-1-0-add-ignore-deprecations-for-ts6在 Nx 的迁移清单中注册于版本23.1.0-beta.8并带有一个关键门控条件migrations.json{ 23-1-0-add-ignore-deprecations-for-ts6: { version: 23.1.0-beta.8, description: ……, requires: { typescript: 6.0.0 }, factory: ./dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6, documentation: ./dist/src/migrations/update-23-1-0/add-ignore-deprecations-for-ts6.md } }也就是说该迁移只在工作区实际运行 TypeScript 6 时才会执行requires条件不满足会自动跳过并且在每个命中的tsconfig*.json上以两遍扫描的方式工作源码中的 Pass 1 / Pass 2 注释Pass 1写固定与加载标志为所有链根没有extends的配置文件补齐缺失的四条默认值同时为每个文件名恰好为tsconfig.json的文件写入配置加载标志。之所以要先写是因为 Pass 2 的extends解析要读到这些刚落盘的内容。Pass 2压制废弃值让 TypeScript 自己解析每个配置文件extends合并后的有效选项凡命中上述废弃值清单且有效ignoreDeprecations不是6.0的就补上该标志。两遍都通过globAsync(tree, [**/tsconfig*.json])收集文件最终统一调用formatFiles(tree)格式化。树友好的解析宿主让 extends 解析看得见待写入内容Pass 2 调用 TypeScript 的parseJsonConfigFileContent时传入的是createTreeParseConfigHost(tree)生成的宿主ts-config.ts。它的关键作用有两点基于 Nx 内存树Tree回答文件存在性与内容读取因此能解析到 Pass 1 刚写入、尚未落盘的修改也能解析到node_modules中包提供的 base 配置naive 的tree.read宿主做不到后者readDirectory被实现为空操作迁移只关心合并后的compilerOptions不需要扫描源文件列表从而大幅减少解析开销。测试用例中专门覆盖了多种extends形式普通相对路径、无扩展名的./base、数组形式[./base-a.json, ./base-b.json]TypeScript 从左到右合并、后者覆盖前者、包形式tsconfig/base/base.json。在 flags a child that inherits a deprecated value through an array-form extends 用例中base-a是干净的bundler解析而base-b的node10覆盖了它合并结果带废弃值子配置因此必须自带标志——两个 base 都不是tsconfig*.json命名永远不会被收集和编辑。三条写入规则详解规则一为链根固定四条 TypeScript 6 被翻转的默认值DEFAULT_PRESERVING_PINSadd-ignore-deprecations-for-ts6.ts定义了四组要固定到链根own.extends undefined上的键值const DEFAULT_PRESERVING_PINS: ReadonlyArray[string, boolean | string[]] [ [strict, false], [noUncheckedSideEffectImports, false], [types, [*]], [esModuleInterop, false], ];写入遵循缺失才补原则只有链根上没有显式设置该键时才写入用户显式配置过的值无论strict: true还是strict: false一律不动。这一点被测试明确锁定does not overwrite an explicit strict true显式strict: true保持不变does not overwrite an explicit types list显式types: [node]保持不变does not overwrite an explicit empty types array显式types: []有意退出也保持不变keeps an explicit esModuleInterop truetrue是 TS6 的新默认自然不覆盖。types: [*]的通配符写法用于恢复 TypeScript 5 的自动加载全部 types行为——这是 ts-node 对jest.config.ts做类型检查时能找到types/node的关键。而esModuleInterop: false由于本身已废弃Pass 2 会在同一次运行中为它补上ignoreDeprecations将其静默源码注释明确说明这个 false 固定要先于废弃压制执行so the added false is silenced in the same run。规则二为所有 tsconfig.json 写入配置加载标志与只针对链根、只针对命中废弃值的其他写入不同文件名恰好为tsconfig.json的文件无条件写入ignoreDeprecations: 6.0。原因在文档和源码中解释得很清楚jest 与 ts-node 编译配置文件如jest.config.ts时会从工作目录向上查找并自动加载名为tsconfig.json的文件注意不是从配置文件自身所在目录查找ts-node 在配置未设置target时会注入默认值target: es5而es5正是 TypeScript 6 的废弃值TS5107哪怕这个tsconfig.json本身干干净净也会在加载时报错该标志会被 ts-node 透传从而保住这次配置加载在没有任何实际废弃值时它是惰性的、无副作用的。测试always flags a clean chain-root tsconfig.json but not a clean tsconfig.base.json精确验证了这条只认名字的规则干净的tsconfig.json获得标志而干净的tsconfig.base.json不是自动加载目标保持原样。规则三基于合并后的有效选项决定是否补标志Pass 2 的判定不是看文件自身写了什么而是看TypeScript 合并extends链之后的有效选项。这带来三个精妙的行为继承到废弃值也补子配置从迁移不会编辑的 base如包提供的tsconfig/*预设、非tsconfig*.json命名的base.json继承到node10时子配置会自带标志。测试用例 flags a child whose deprecated value comes from a non-tsconfig-named base 验证了这一点base 保持原样子配置直接补标志。已经继承到6.0就不重复写如果子配置通过extends已经获得了有效的6.0则不再冗余写入。测试 does not re-flag a descendant that inherits the flag from tsconfig.json 验证tsconfig.spec.json继承自已带标志的tsconfig.json即使它自己写了moduleResolution: node10也不会重复补标志。过期的本地5.0会被升级为6.0一个本地ignoreDeprecations: 5.0会覆盖继承来的6.0导致废弃错误仍然爆发因此必须升级。测试用例 upgrades a stale local flag that overrides an inherited 6.0 与 upgrades a stale local flag when the deprecated value is inherited 覆盖了本地值废弃与继承值废弃两种方向。此外ts-node.compilerOptions这个 overlay 块被单独检查tsc不会合并它主块刚写入的6.0也不一定能可靠地传导到 ts-node 的运行时覆盖层不同 ts-node 版本行为不一所以只要 overlay 自身或解析后的主配置带有废弃值就直接给 overlay 单独补标志。测试 adds ignoreDeprecations to a ts-node.compilerOptions block 与 adds ignoreDeprecations to both compilerOptions and ts-node block 分别验证了两种组合。两类被有意跳过的文件迁移文档明确列出了两类不参与固定、但可能仍参与标志写入的文件使用extends的文件它们从链根继承四条固定值因此不重复固定。测试does not touch strict on a file that has extends验证strict不会被写入这种文件。纯 solution 式容器files: []且没有include它们不选择任何源文件不获得四条固定但名字恰好是tsconfig.json的 solution 容器仍会获得配置加载标志jest/ts-node 加载场景与选源无关。测试 adds only the config-load flag to a solution-container tsconfig.json 验证输入{ files: [] }后输出{ compilerOptions: { ignoreDeprecations: 6.0 } }。还有一个防御性细节如果compilerOptions字段存在但不是对象例如[]迁移会原样跳过该文件避免modify()抛异常中断整场迁移——测试 leaves a non-object compilerOptions untouched without crashing 与 leaves a non-object compilerOptions untouched even when it inherits a deprecated value 覆盖了这两种情况。边界情况与失败处理extends 解析失败时显式告警Pass 2 使用extendsResolutionFailedts-config.ts检查解析结果如果某个 base 既不在树中、tsc也读不到合并选项就是不完整的从该 base 继承的废弃值可能被漏掉。此时迁移不猜测、不静默而是输出logger.warn提示该配置文件本身无法编译需要先修复。这是宁可显式暴露、不可偷偷修复的设计取舍。幂等性迁移对所有场景都保证幂等第二次运行不会产生任何额外修改。测试中is idempotent与is idempotent for the strict-pin pass分别验证了整体与单遍的幂等性。此外迁移基于jsonc-parser的parseTree/modify/applyEdits做结构化编辑并保留注释与格式keepLines: true, insertSpaces: true, tabSize: 2测试 preserves comments when adding the flag 验证了注释得以保留。一次典型迁移的完整效果文档给出了最直观的示例。一个链根tsconfig.json修改前{ compilerOptions: { target: es5, module: esnext, moduleResolution: bundler } }迁移后{6-10}标出的是新增行{ compilerOptions: { target: es5, module: esnext, moduleResolution: bundler, strict: false, noUncheckedSideEffectImports: false, types: [*], esModuleInterop: false, ignoreDeprecations: 6.0 } }观察这个结果可以完整印证前文所有规则target: es5是废弃值故补ignoreDeprecations: 6.0strict、noUncheckedSideEffectImports、types、esModuleInterop四条被固定以保留 TS5 语义esModuleInterop: false本身的废弃告警被同一次写入的6.0静默。迁移完成后Nx 会输出三条logger.info摘要分别统计获得加载标志的tsconfig.json数量、补上废弃压制标志的文件数量、以及完成默认值固定的链根数量见 add-ignore-deprecations-for-ts6.ts。与同批迁移的配合rootDir 固定TypeScript 6 的破坏性变化不止默认值翻转rootDir的推断规则也变了TS5 推断为程序非声明输入文件的公共目录TS6 改为配置文件自身所在目录导致 spec/e2e 配置通过paths别名导入其他项目源码时出现TS5011/TS6059。Nx 23.1.0 在同一版本提供了配套迁移23-1-0-set-tsconfig-root-dir-for-ts6见 set-tsconfig-root-dir-for-ts6.md同样requiresTypeScript6.0.0把rootDir固定到 TS5 推断出的值。升级 TypeScript 6 时两条迁移配合执行才能完整保住编译与产物布局。适用前提与限制该迁移仅在工作区 TypeScript 版本满足6.0.0时执行且属于 Nx 23.1.0 及后续版本的能力在 TypeScript 5.x 工作区中运行不会触发。迁移的定位是在不迁移到完整 TypeScript 6 配置的前提下让存量工作区继续编译它通过压制废弃告警换取兼容不能消除module/moduleResolution组合错误TS5110例如 ts-node 强制module: commonjs撞上继承来的nodenext解析也不处理noUncheckedSideEffectImports: true带来的语义诊断TS2882这是语义错误而非废弃错误ignoreDeprecations无法压制。esModuleInterop: false的固定只是把互操作语义变化推迟到 TypeScript 7 的迁移属于有意的渐进式策略而非永久方案升级到 TS7 时仍需处理import * as x from cjs的调用语义变化。如果你想在本地验证或深入这些行为可以直接阅读 迁移源码 与 1100 余行的 测试套件测试覆盖了本文提到的每一条规则与边界情况是理解 TypeScript 6 破坏性变更的最佳实操教材。【免费下载链接】nxThe Monorepo Platform that amplifies both developers and AI agents. Nx optimizes your builds, scales your CI, and fixes failed PRs automatically. Ship in half the time.项目地址: https://gitcode.com/GitHub_Trending/nx/nx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表