ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

ESLint 5.0.0 升级迁移指南:全面解析 v5 破坏性变更与实战应对方案

ESLint 5.0.0 升级迁移指南:全面解析 v5 破坏性变更与实战应对方案 ESLint 5.0.0 升级迁移指南全面解析 v5 破坏性变更与实战应对方案【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslintESLint v5.0.0 是项目的第五个大版本发布它在保持大部分用户无需修改构建即可升级的同时引入了一系列有意的破坏性变更。本文以官方迁移文档docs/src/use/migrating-to-5.0.0.md为核心骨架逐条拆解面向普通用户、插件/自定义规则开发者以及集成开发者三大类变更的来龙去脉、影响范围与升级对策并结合当前仓库源码验证这些变更在后续版本中的实际形态帮助你安全、平滑地完成 v4 → v5 的升级。版本背景与升级总览ESLint v5 的破坏性变更按受影响人群分为三类列表顺序大致按预期影响用户数量从多到少排列面向普通用户Node.js 4 不再受支持eslint:recommended新增两条规则experimentalObjectRestSpread选项弃用命令行 lint 不存在的文件变为致命错误部分规则默认选项变更node、browser、jest环境中移除废弃全局变量空文件也会被 lint作用域包中的插件可在配置中解析多行eslint-disable-line指令会被报告为问题面向插件 / 自定义规则开发者AST 节点的parent属性在规则运行前设置默认解析器下展开运算符类型为SpreadElement默认解析器下剩余运算符类型为RestElement默认解析器下 JSX 文本节点类型为JSXTextcontext.getScope()返回更正确的 scope规则上下文对象上的_linter属性被移除RuleTester断言改用严格相等规则上报问题时必须提供消息面向集成开发者单条 lint 消息上不再有source属性致命错误导致退出码为 2eslint.linter属性变为不可枚举下文逐一展开。面向普通用户的破坏性变更Node.js 4 不再受支持自 2018 年 4 月 30 日起Node.js 4 进入 EOL生命周期结束阶段不再接收安全更新因此 ESLint v5 正式放弃对它的支持。v5 支持的 Node.js 版本为Node.js 66.14.0 及以上Node.js 88.10.0 及以上Node.js 9.10.0 以上的任何版本应对方案使用 ESLint v5 时至少升级到 Node.js 6。如果暂时无法升级建议继续使用 ESLint v4.x直到 Node 环境就绪后再迁移。后续版本的迁移文档如docs/src/use/migrating-to-6.0.0.md、docs/src/use/migrating-to-7.0.0.md等会继续收窄 Node 支持范围升级时请留意 Node 版本要求。eslint:recommended新增两条规则v5 向eslint:recommended预定义配置中新增了两条规则for-direction强制for循环的更新子句将计数器朝正确方向移动。getter-return强制属性 getter 中包含return语句。这两条规则在当前仓库中依然是推荐规则lib/rules/for-direction.js的meta.docs.recommended为truelib/rules/getter-return.js同样如此自动生成的预定义配置packages/js/src/configs/eslint-recommended.js中两者均配置为for-direction: error、getter-return: error该文件由tools/update-eslint-recommended.js脚本自动生成勿手工编辑。应对方案若希望保持 v4 的行为可在配置文件中显式关闭这两条规则{ extends: eslint:recommended, rules: { for-direction: off, getter-return: off } }experimentalObjectRestSpread选项已弃用在 v4 及更早版本中使用默认解析器时可以通过parserOptions.ecmaFeatures.experimentalObjectRestSpread开启对象 rest/spread 支持{ parserOptions: { ecmaFeatures: { experimentalObjectRestSpread: true } } }对象 rest/spread 已成为 JavaScript 语言的正式特性不再属于实验性支持。在 ESLint v4 与 v5 中对象 rest/spread 都可以通过ecmaVersion: 2018开启{ parserOptions: { ecmaVersion: 2018 } }注意ecmaVersion: 2018同时会开启 ES2018 的其他语法特性例如 async iteration。使用 v5 默认解析器时无法再独立于其他特性单独开关对象 rest/spread 的语法支持。为了兼容ESLint v5 会把配置中出现的ecmaFeatures: { experimentalObjectRestSpread: true }当作ecmaVersion: 2018的别名处理——因此若你使用对象 rest/spread代码在 v5 下仍可正常解析但会收到弃用警告。该别名已在 ESLint v6 中移除。应对方案升级到 v5 后应尽快把配置改为ecmaVersion: 2018以消除弃用警告如需禁止使用其他 ES2018 特性可借助no-restricted-syntax等规则进行限制。命令行 lint 不存在的文件现在是致命错误在 v4 及更早版本中命令行提供的文件和 glob 如果不存在ESLint 会静默忽略eslint nonexistent-file.js nonexistent-folder/**/*.js # ESLint v4 下无任何报错退出很多用户觉得这种行为令人困惑文件名一旦拼写错误ESLint 看起来成功lint 了该文件实际上什么都没有检查。v5 在满足以下任一条件时报告致命错误命令行提供的某个文件不存在命令行提供的某个 glob 或目录没有匹配到任何可 lint 的文件。注意该行为同样作用于CLIEngine.executeOnFiles()API。应对方案升级后若遇到文件缺失类报错先检查传入 ESLint 的路径是否有拼写错误要消除该错误直接把这些文件或 glob 从命令行参数中移除即可。如果使用了依赖旧行为的脚手架生成器例如在新项目里生成一条eslint tests/的脚本而当时尚无任何测试文件可以添加一个能匹配该模式的占位文件如空的tests/index.js来绕过问题。部分规则的默认选项已变更v5 调整了两条规则的默认选项object-curly-newline的默认选项由{ multiline: true }变为{ consistent: true }no-self-assign的默认选项由{ props: false }变为{ props: true }。这两个默认值在后续版本中延续至今当前仓库lib/rules/object-curly-newline.js的归一化逻辑中当用户未提供选项时consistent默认为truelib/rules/no-self-assign.js的defaultOptions为[{ props: true }]即默认也会检查成员表达式obj.x obj.x这类自赋值并标记props: true。应对方案若想恢复 v4 的行为可在配置中显式写入旧选项{ rules: { object-curly-newline: [error, { multiline: true }], no-self-assign: [error, { props: false }] } }node、browser、jest环境中移除了废弃全局变量部分在 Node.js、浏览器和 Jest 环境中已经废弃或移除的全局变量被从对应的 ESLint 环境定义中剔除。例如浏览器曾向 JS 代码暴露SVGAltGlyphElement全局变量但它已从 Web 标准中移除、浏览器中不再存在。移除后在这些环境中使用废弃全局变量会触发no-undef等规则报错。应对方案如果确实需要继续使用这些废弃全局变量可以在配置的globals段中重新启用{ env: { browser: true }, globals: { SVGAltGlyphElement: false } }globals值为false表示该全局变量存在但不可写true表示允许写入。空文件现在也会被 lintv4 有一个特殊行为对仅包含空白字符的文件ESLint 会跳过解析器和规则并始终返回零错误。这给规则作者带来了困惑尤其是写规则测试时为样式类规则编写源码只含空白的测试本意是验证规则在无适用代码时的表现但旧行为下规则根本不会运行导致该规则某一方面始终未被测试覆盖。v5 将纯空白文件与其他文件一视同仁会正常解析并执行已启用的规则。如果你有自定义规则对空文件上报错误升级后可能产生新的 lint 问题。应对方案项目中的空文件如果不希望被 lint可将其加入.eslintignore扁平配置时代可参考docs/src/use/configure/ignore.md中关于 ignores 的说明。自定义规则作者则应确保规则能正确处理空文件——大多数情况下无需任何改动。作用域包中的插件现在可在配置中解析v5 遇到配置中以开头的插件名时会按 npm 作用域包scoped package的方式解析。例如配置写plugins: [foo]v5 会尝试加载foo/eslint-plugin这个包而 v4 会尝试加载eslint-plugin-foo。由于 npm 发布包名中间不允许出现字符绝大多数用户并不会依赖旧行为但这是一项破坏性变更。应对方案如果依赖eslint-config-foo这类包名被 ESLint 加载建议将其重命名为不含的合法包名。多行eslint-disable-line指令会被报告为问题eslint-disable-line与eslint-disable-next-line指令注释只允许占据单行。例如下面这条指令注释是无效的alert(foo); /* eslint-disable-line no-alert */ alert(bar); // 这条指令到底禁用的是哪一行旧版本会忽略这类格式错误的指令注释v5 会在发现此类问题时上报错误便于尽早修正。应对方案升级后若出现新增报错请确保eslint-disable-line指令只占一行。注意/* */块注释仍可用于指令前提是块注释内部不含换行。面向插件 / 自定义规则开发者的破坏性变更AST 节点的parent属性在规则运行前设置旧版本中ESLint 会在即将运行某节点的规则监听器前才设置该节点的parent属性导致规则作者在规则启动时看到所有节点都没有parent有时不得不为了在需要时拿到parent而把规则结构搞得很复杂。v5 中parent属性在所有规则接触 AST 之前就已设置完毕规则编写因此更简单——parent始终可用而非在后台被动态修改。副作用是规则第一次看到 AST 时它就是循环结构旧版本要在首个监听器调用后才变为循环结构。因此如果自定义规则通过枚举节点的所有属性来遍历 AST又没有正确处理环可能会无限循环或内存耗尽。应对方案如果自定义规则枚举了 AST 节点的全部属性请排除parent属性或实现环检测以确保结果正确。默认解析器下展开运算符类型为SpreadElement在 v4 中若启用了experimentalObjectRestSpread解析const foo {...data}时...data会生成ExperimentalSpreadProperty节点类型。v5 的默认解析器始终将...data标记为SpreadElement类型——即使启用了现已弃用的experimentalObjectRestSpread也一样从而使 AST 符合当前 ESTree 规范。应对方案若自定义规则依赖ExperimentalSpreadProperty类型请更新为同时兼容SpreadElement类型。默认解析器下剩余运算符类型为RestElement同理v4 在启用experimentalObjectRestSpread时解析const {foo, ...rest} data会生成ExperimentalRestProperty节点v5 默认解析器始终使用RestElement类型即使启用了旧选项以保证 AST 符合 ESTree 规范。应对方案若自定义规则依赖ExperimentalRestProperty类型请更新为同时兼容RestElement类型。默认解析器下JSX 文本节点类型为JSXText解析afoo/a这类 JSX 代码时v5 默认解析器将文本节点foo标记为JSXText类型而非旧的Literal类型以符合 JSX 规范的最新更新。应对方案若自定义规则依赖 JSX 元素文本节点为Literal类型请更新为同时兼容JSXText类型。context.getScope()现在返回更正确的 scope旧版context.getScope()的行为会随parserOptions.ecmaVersion变化这在解析器不响应ecmaVersion选项如babel-eslint时会造成困惑。此外它在CatchClauseES5、ForStatement/ForInStatement≥ES2015、ForOfStatement和WithStatement节点上会错误地返回正确 scope 的父级 scope。v5 中context.getScope()的行为不再受parserOptions.ecmaVersion影响并返回正确的 scope。具体各节点返回哪些 scope可参考 scope-manager 接口文档。应对方案在节点处理器中使用context.getScope()的自定义规则可能需要根据修正后的 scope 信息调整逻辑。规则上下文对象上的_linter属性被移除旧版本规则上下文对象上存在一个未文档化的_linter属性ESLint 内部用它处理规则上报的结果。部分规则借助它实现了官方并不打算开放的能力——例如某些插件在一个规则里监听其他规则的上报以检查是否存在未使用的/* eslint-disable */指令注释。这个能力虽然对用户有用但也可能带来稳定性问题某个插件中一条规则的升级可能意外导致另一插件中的规则开始报错。_linter属性已在 v5.0 移除无法再以此实现规则。不过--report-unused-disable-directivesCLI 标志可以用来标记未使用的指令注释。应对方案若你的插件曾通过_linter实现上述功能请改用--report-unused-disable-directives命令行标志。RuleTester断言改用严格相等旧版RuleTester在部分断言中使用宽松相等loose equality。例如规则 autofix 后产出字符串7RuleTester的output断言会容忍数字7。v5 中RuleTester的比较全部使用严格相等这类断言将不再通过。应对方案使用RuleTester编写自定义规则测试时请确保断言中的期望值与实际值严格相等类型也必须一致。规则上报问题时必须提供消息旧版本允许规则上报 AST 节点而不附带报告消息这并非预期行为——默认 formatter 会在规则缺失消息时崩溃但使用json等非默认 formatter 时可以侥幸不崩溃。v5 中上报问题而不提供消息一律视为错误。应对方案若自定义规则存在上报问题但不带消息的写法请改为在上报时提供消息messageId或message。面向集成开发者的破坏性变更单条 lint 消息上不再有source属性早在 2016 年 10 月的 ESLint v3.8.0 发布说明中就已预告source属性将从单条 lint 消息对象上移除v5 正式生效。应对方案若 formatter 或集成代码依赖单条消息上的source属性请改用文件级结果对象file results object上的source属性。致命错误导致退出码为 2使用 ESLint v4 时以下两种场景的命令行退出码都是 1集成方难以区分lint 成功完成但存在若干 lint 错误因致命错误如配置文件无效导致 lint 未成功执行。v5 中因致命错误导致的未成功 lint 运行退出码改为 2 而非 1。应对方案若集成代码用退出码是否等于 1来判断所有问题请改为检查退出码是否为非零值。eslint.linter属性变为不可枚举在使用 ESLint 的 Node.js API 时linter属性现在不可枚举。注意linter属性在 v4 中已被弃用取而代之的是Linter属性。应对方案若依赖枚举eslint对象的所有属性请改用Object.getOwnPropertyNames以捕获不可枚举键。迁移检查清单完成 v4 → v5 升级时可按以下顺序自查确认 Node.js 版本 ≥ 6.14.0推荐 ≥ 8.10.0升级后先跑一次 lint排查新增的for-direction、getter-return报错视需要按上文配置关闭全局搜索配置中的experimentalObjectRestSpread替换为ecmaVersion: 2018检查命令行传入的文件/glob 是否真实存在移除失效路径或添加占位文件检查object-curly-newline、no-self-assign默认选项变更对代码风格的影响若在node/browser/jest环境中用到废弃全局变量在globals段显式声明将空文件加入 ignore 列表如不希望被 lint自定义规则侧核对parent属性、SpreadElement/RestElement/JSXText节点类型、context.getScope()语义、上报消息完整性并将RuleTester断言改为严格相等集成侧单条消息不再含source致命错误退出码为 2eslint.linter不可枚举。总结ESLint v5 的破坏性变更大多遵循更符合规范、更不易误用、更利于集成的原则AST 节点类型对齐 ESTree/JSX 规范、parent与 scope 语义修正、RuleTester收紧相等性、上报消息强制完整、命令行与退出码语义更加明确。大部分普通用户只需修改少量配置即可完成升级而规则作者与集成开发者则需要对照上文逐项核对。若需查阅更早或更晚版本的迁移路径仓库中还保留了docs/src/use/migrating-to-1.0.0.md至docs/src/use/migrating-to-7.0.0.md、docs/src/use/migrate-to-8.0.0.md、docs/src/use/migrate-to-9.0.0.md与docs/src/use/migrate-to-10.0.0.md等系列迁移指南可一并参考。【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表