ARTICLE DETAIL

资讯详情

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

ESLint v6.0.0 迁移指南:破坏性变更全解析与升级实践

ESLint v6.0.0 迁移指南:破坏性变更全解析与升级实践 ESLint v6.0.0 迁移指南破坏性变更全解析与升级实践【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslintESLint v6.0.0 是 ESLint 的一个主版本major release引入了若干破坏性变更breaking changes。本篇指南以官方迁移文档为骨架逐条讲解这些变更对普通用户、插件/自定义规则开发者以及集成开发者三类人群的影响并结合当前仓库源码给出佐证与可复制的修复配置。读完本文你将能系统评估自己项目受 v6.0.0 影响的范围并按指南完成升级。说明以下变更列表大致按预计影响用户数量从多到少排列排在前面的变更影响面最大。文档正文中的相关 issue 链接因仓库只读展示此处保留其编号以便回溯。一、面向普通用户的破坏性变更1. 不再支持 Node.js 6自 2019 年 4 月起Node.js 6 进入 EOL生命周期结束状态不再接收安全更新。因此 ESLint v6 放弃了对它的支持v6 支持的 Node.js 版本为Node.js 88.10.0 及以上Node.js 1010.13.0 及以上Node.js 11.10.1 以上任意版本处理方式使用 ESLint v6 时请确保 Node.js 至少升级到 8。如果暂时无法升级建议继续使用 ESLint v5.x直到 Node.js 升级完成。2.eslint:recommended配置已更新eslint:recommended是 ESLint 内置的预定义配置使用方式为extends: eslint:recommendedflat config 下为eslint/js的recommended配置。v6.0.0 对其做了三处调整新增进入 recommended 的规则共 7 条规则作用no-async-promise-executor禁止将async函数作为Promise构造器参数通常是 bugno-misleading-character-class报告正则字符类中可能不符合预期的字符no-prototype-builtins报告foo.hasOwnProperty(bar)这类调用建议改为Object.prototype.hasOwnProperty.call(foo, bar)no-shadow-restricted-names禁止遮蔽undefined等保留名称如let undefined 5;避免误导读者no-useless-catch报告冗余的catch子句删除后不影响行为no-with禁止使用with语句它会使代码难以理解并引发兼容性问题require-atomic-updates报告 async 函数中变量重新赋值可能导致的竞态条件 bug从 recommended 中移除的规则1 条no-console禁止调用console.log等。虽然它在很多场景下有用例如避免生产代码残留调试语句但它不像 recommended 中其他规则那样普适且在某些场景如 CLI 应用会误报故被移除。行为语义变化在 v5 中eslint:recommended会显式关闭所有未被视为 recommended 的核心规则这导致当eslint:recommended在另一个配置之后加载时会意外关闭部分规则。v6 中eslint:recommended对非 recommended 规则不再有任何影响。处理方式如需完全复刻 v5.x 的eslint:recommended行为可在配置文件中显式开关规则{ extends: eslint:recommended, rules: { no-async-promise-executor: off, no-misleading-character-class: off, no-prototype-builtins: off, no-shadow-restricted-names: off, no-useless-catch: off, no-with: off, require-atomic-updates: off, no-console: error } }极少数情况下如果你依赖了 v5 中eslint:recommended关闭核心规则的旧行为可能还需要关闭更多规则才能恢复旧行为。源码佐证在当前仓库中eslint:recommended的实际规则列表由 packages/js/src/configs/eslint-recommended.js 定义该文件由tools/update-eslint-recommended.js脚本自动生成勿手动编辑。可以看到no-async-promise-executor、no-misleading-character-class、no-prototype-builtins、no-shadow-restricted-names、no-useless-catch、no-with均以error出现而no-console不在列表中。测试文件 tests/conf/eslint-recommended.js 也验证了“recommended 规则配置为 error”与“非 recommended 规则如camelcase不被配置”这两个约定。3. 插件与可分享配置的加载不再受 ESLint 自身位置影响此前 ESLint 相对于 ESLint 包自身的位置加载插件因此官方建议全局安装 ESLint 就全局装插件本地安装就本地装插件。但由于设计缺陷这种策略在使用lerna、Yarn Plug n Play 等包管理工具时会导致插件和可分享配置随机加载失败。v6 的规则是插件始终应该本地安装即使 ESLint 是全局安装的。更精确地说v6 默认相对于最终用户的项目解析插件而可分享配置和解析器始终相对于导入它们的配置文件位置解析。处理方式如果使用全局 ESLint如npm install eslint --global配合插件请在运行 ESLint 的项目中本地安装这些插件。如果配置文件扩展了可分享配置和/或解析器请确保这些包作为包含该配置文件项目的依赖安装。如果配置文件位于本地项目之外通过--config标志使用请考虑将插件安装为该配置文件的依赖并设置--resolve-plugins-relative-to标志指向配置文件位置。4. 默认解析器对选项的校验更严格espreeESLint 的默认解析器在以下情况会直接报错ecmaVersion解析器选项被设置为非数字值如字符串2015此前非数字选项会被静默忽略。设置了sourceType: module但ecmaVersion为5或未指定此前设置sourceType: module会隐式将ecmaVersion提升到至少 2015可能令人意外。sourceType被设置为script或module以外的值。处理方式如果配置将ecmaVersion设为非数字可删除ecmaVersion恢复旧行为但建议确认配置实际是否按预期工作。如果配置设置了parserOptions: { sourceType: module }而未设置parserOptions.ecmaVersion应添加parserOptions: { ecmaVersion: 2015 }恢复旧行为。5. 规则配置校验更严格为尽早发现配置错误v6 会在配置不存在的规则时报 linting 错误配置ESLint v5ESLint v6/*eslint-enable foo*/无错误linting 错误/*eslint-disable(-line) foo*/无错误linting 错误/*eslint foo: 0*/无错误linting 错误{rules: {foo: 0}}无错误无错误{rules: {foo: 1}}linting 警告linting 错误处理方式删除内联配置中不存在的规则。6.no-redeclare规则默认更严格no-redeclare的默认选项从{ builtinGlobals: false }变为{ builtinGlobals: true }。此外如果/* global foo */这样的注释声明的全局变量已通过配置启用该规则现在也会报错。处理方式{ rules: { no-redeclare: [error, { builtinGlobals: false }] } }另外如果代码中出现新的global注释报错请删除这些注释。源码佐证当前仓库 lib/rules/no-redeclare.js 中defaultOptions: [{ builtinGlobals: true }]并在create中通过const [{ builtinGlobals }] context.options;读取schema 中builtinGlobals: { type: boolean }。代码逻辑lib/rules/no-redeclare.js会遍历变量声明当builtinGlobals为真且变量由eslintImplicitGlobalSetting即/* global */注释引入时将其计为一次“builtin”声明从而对再次声明报redeclaredAsBuiltin错误。7.comma-dangle规则默认更严格此前comma-dangle会忽略函数尾随参数和形参除非显式配置检查函数逗号。v6 中函数逗号与其他类型尾随逗号同等对待。处理方式恢复旧的默认行为{ rules: { comma-dangle: [ error, { arrays: never, objects: never, imports: never, exports: never, functions: ignore } ] } }若要恢复字符串选项如always-multiline的旧行为将上例中的never替换为always-multiline即可。源码佐证当前仓库 lib/rules/comma-dangle.js 的DEFAULT_OPTIONS中functions: never说明该规则在后来配合 es2017 的尾逗号语法已默认检查函数逗号其 schema 的valueWithIgnore枚举允许ignorelib/rules/comma-dangle.js这正是上述迁移配置中functions: ignore的合法取值依据。8.no-confusing-arrow规则默认更宽松no-confusing-arrow的默认选项从{ allowParens: false }变为{ allowParens: true }。处理方式恢复旧的默认行为{ rules: { no-confusing-arrow: [error, { allowParens: false }] } }9.overrides现在可以匹配 dotfiles由于 bug此前配置文件中overrides区块files列表里的 glob 模式永远不会匹配点文件dotfiles导致无法让 override 应用到以点开头的文件。此 bug 已在 v6 修复。处理方式如果不想让 dotfile 被 override 匹配可在该overrides区块添加excludedFiles: [.*]。更多细节见 docs/src/use/configure/index.md 中基于 glob 模式配置的说明。10. 扩展配置中的overrides现在可以被父配置覆盖此前存在一个 bug可分享配置中的overrides区块优先级高于父配置的顶层规则。例如下面的配置中semi规则最终会被启用尽管最终用户的配置里显式关闭了它// .eslintrc.js module.exports { extends: [foo], rules: { semi: off, }, };// eslint-config-foo/index.js module.exports { overrides: { files: [*.js], rules: { semi: error, }, }, };在 v6.0.0 中父配置始终优先于扩展配置即使涉及overrides区块也是如此。处理方式预计影响面很小因为大多数可分享配置不使用overrides。但如果你使用的可分享配置带overrides可能因自己配置中此前未生效的显式条目而遇到行为变化。若想继承可分享配置的行为只需删除自己配置中的对应条目上例中删除.eslintrc.js里的semi: off即可恢复旧行为。11. globals 的配置值现在会被校验此前用对象配置一组全局变量时值可以是任意内容未知值会被当作writable处理// .eslintrc.js module.exports { globals: { foo: readonly, bar: writable, baz: hello!, // ??? }, };v6 起globals对象中的任何未知值都会导致配置校验错误。处理方式确保所有 globals 的取值是readonly、writable或off之一ESLint 为兼容性也接受一些替代拼写和变体。源码佐证当前仓库的 flat config 校验层 lib/config/flat-config-schema.js 中定义了ALLOWED_SEVERITIES new Set([error, warn, off, 2, 1, 0])并对未知取值抛出 “Expected one of: ... or a boolean.” 之类的错误体现了“配置值强校验”这一设计方向的延续。12. 已废弃的experimentalObjectRestSpread选项被移除此前使用默认解析器时可通过该选项启用对象 rest/spread 属性的解析支持{ parserOptions: { ecmaFeatures: { experimentalObjectRestSpread: true } } }自 v5 起ecmaFeatures: { experimentalObjectRestSpread: true }等价于ecmaVersion: 2018并会输出弃用警告。v6 中该特性被彻底移除、不再生效。如果配置依赖它启用 ES2018 解析近期语法可能开始出现解析错误。处理方式改用{ parserOptions: { ecmaVersion: 2018 } }如果不确定哪个配置文件需要更新可先运行 ESLint v5查看弃用警告中提到的配置文件。13. 规则选项中的用户正则表达式以 unicode 标志解析max-len等规则接受一个被解释为正则表达式的字符串选项。v6.0.0 起这些正则表达式以 unicode 标志解析在匹配星形符号astral symbols等字符时行为更合理同时 unicode 正则对转义序列的校验比非 unicode 正则更严格。处理方式升级后若出现规则选项校验错误请确保规则选项中的正则表达式没有无效的转义序列。二、面向插件 / 自定义规则开发者的破坏性变更1. 插件作者可能需要更新安装说明如果你维护插件并提供安装说明请确保说明与上文“插件加载方式变更”保持一致。特别是用generator-eslint包生成的插件很可能包含面向全局 ESLint 安装的过时说明。2.RuleTester现在会校验规则 schema 中无效的default关键字规则 schema 有时用default关键字自动指定规则选项的默认值。但default只在特定 schema 位置生效其他位置会被忽略——如果规则错误地期待某个默认值作为规则选项被传入就容易产生 bug。v6.0.0 起RuleTester会在规则 schema 含无效default关键字时报错。处理方式如果RuleTester报告无效 default 错误删除规则 schema 中对应位置的default属性即可规则行为不变同时建议验证该位置不传选项值时规则是否表现正确。3.RuleTester的parser选项现在要求绝对路径此前测试中使用自定义解析器时parser属性可传包名或文件路径。但传包名时测试器无法确定从何处加载解析器包因为它不知道是哪些文件在运行测试。v6.0.0 起RuleTester禁止parser属性使用包名。处理方式如果测试用例中使用包名作为parser请改用require.resolve()将包名解析为绝对路径const RuleTester require(eslint).RuleTester; const ruleTester new RuleTester({ parser: require.resolve(my-parser), // 包名 → 绝对路径 });4.eslintExplicitGlobalComment作用域分析属性被移除此前 ESLint 会在作用域分析的Variable对象上添加eslintExplicitGlobalComment属性表示变量由/* global */注释引入。该属性从未被文档化ESLint 团队未在核心之外找到任何使用场景因此在 v6 中移除替换为eslintExplicitGlobalComments属性——当变量由多个/* global */注释声明时它以列表形式包含所有这些注释。处理方式如果你维护的规则使用了eslintExplicitGlobalComment请改为使用列表形式的eslintExplicitGlobalComments。源码佐证当前仓库 lib/rules/no-redeclare.js 正是遍历variable.eslintExplicitGlobalComments复数、列表来逐个处理/* global */注释声明印证了新属性的实际用法。三、面向集成开发者的破坏性变更1. 插件与可分享配置加载方式变更与用户侧变更相同插件始终应本地安装可分享配置与解析器始终相对于导入它们的配置文件解析。集成方同样需要遵循该规则详见上文第 3 节。2.Linter不再尝试从文件系统加载缺失的解析器此前当对尚未定义的解析器进行 lint 时LinterAPI 会尝试从文件系统加载解析器。但由于Linter在其他任何情况下都不访问文件系统这种行为令人困惑且难以保证从文件系统加载时找到正确的解析器。v6 中Linter不再执行任何文件系统操作包括加载解析器。处理方式如果在Linter中使用自定义解析器请在 lint 任何代码前用Linter#defineParser显式定义解析器const { Linter } require(eslint); const linter new Linter(); linter.defineParser(my-parser, myParserObject); const messages linter.verify(code, { parser: my-parser, });完整的Linter#defineParser用法见 docs/src/integrate/nodejs-api.md。四、升级检查清单按上面各节整理一份升级时可对照执行的清单运行环境确认 Node.js ≥ 8v6 支持 8.10.0、10.13.0、11.10.1。eslint:recommended跑一遍 lint处理新增的 7 条 recommended 规则确认no-console被移除后是否需要自行开启。插件安装确保所有插件在项目内本地安装配置在项目外时使用--resolve-plugins-relative-to。parserOptions删除非数字ecmaVersionsourceType: module搭配显式ecmaVersion: 2015删除experimentalObjectRestSpread并改用ecmaVersion: 2018。规则配置删除配置中不存在的规则按需调整no-redeclare、comma-dangle、no-confusing-arrow的默认值修正 globals 的取值readonly/writable/off检查规则选项正则的转义序列。插件 / 自定义规则更新安装说明移除 schema 中无效的defaultRuleTester的parser改用require.resolve()将eslintExplicitGlobalComment迁移为eslintExplicitGlobalComments。集成代码Linter用defineParser显式注册解析器。参考文档与源码迁移指南原文docs/src/use/migrating-to-6.0.0.md配置入门docs/src/use/configure/index.md 与 docs/src/use/configure/configuration-files.mdNode.js API含Linter#defineParserdocs/src/integrate/nodejs-api.mdeslint:recommended规则清单packages/js/src/configs/eslint-recommended.js由 tools/update-eslint-recommended.js 自动生成eslint:recommended测试tests/conf/eslint-recommended.js规则实现lib/rules/no-redeclare.js、lib/rules/comma-dangle.js配置校验实现lib/config/flat-config-schema.js【免费下载链接】eslintFind and fix problems in your JavaScript code.项目地址: https://gitcode.com/GitHub_Trending/es/eslint创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表