ARTICLE DETAIL

资讯详情

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

eslint-plugin-unicorn 规则实战:`no-unnecessary-fetch-options` 详解

eslint-plugin-unicorn 规则实战:`no-unnecessary-fetch-options` 详解 eslint-plugin-unicorn 规则实战no-unnecessary-fetch-options详解【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicornunicorn/no-unnecessary-fetch-options是 eslint-plugin-unicorn300 条 ESLint 规则集中的一条自动修复型建议规则用于检测并移除fetch()与new Request()调用中多余、等价于省略的RequestInit选项。读完本文你将掌握该规则的全部触发场景、其背后输入是否为Request的类型判断机制、自动修复策略与边界行为并能在自己的 flat config 中正确启用并驾驭它。规则概览为什么要移除多余的 fetch 选项fetch(url, {method: GET})这类写法在语法上完全合法但它把默认值显式写了出来。正如规则文档docs/rules/no-unnecessary-fetch-options.md所说多余的选项会让请求更难一眼扫清。显式写出与默认值相同的选项要么暴露写作者对 API 的不熟悉要么是复制粘贴遗留的冗余无助于可读性。因此本规则的目标是移除那些省略等价的选项——即去掉后行为完全不变。规则元数据rules/no-unnecessary-fetch-options.js#L629-L644显示规则类型suggestion建议性不涉及正确性问题可修复fixable: code可通过 ESLint 的--fixCLI 选项 自动处理无配置项schema: []即开即用不需要也不支持任何参数目标语言js/js。安装与启用flat config该插件要求ESLint10.4、flat config 以及 ESM项目详见 readme.md。安装npm install --save-dev eslint eslint-plugin-unicorn本规则已默认包含在recommended与unopinionated两套预设配置中。如果使用预设无需单独声明若要单独启用在eslint.config.js中配置import unicorn from eslint-plugin-unicorn; import {defineConfig} from eslint/config; import globals from globals; export default defineConfig([ { files: [**/*.js], languageOptions: { globals: globals.builtin, }, plugins: { unicorn, }, rules: { unicorn/no-unnecessary-fetch-options: error, }, }, ]);触发场景一空选项对象最简单的情况是传入一个空对象作为第二个参数它完全等价于不传该参数// ❌ 错误 await fetch(/, {}); // ✅ 正确 await fetch(/);// ❌ 错误 new Request(url, {}); // ✅ 正确 new Request(url);源码中对应MESSAGE_ID_EMPTY_OPTIONSrules/no-unnecessary-fetch-options.js#L31-L37报错信息为Remove unnecessary empty fetch options.。触发场景二与默认值相等的选项RequestInit中有一批选项其取值与规范默认值相同时即可安全移除。源码维护了一张默认值表defaultValuesrules/no-unnecessary-fetch-options.js#L59-L69选项默认值触发示例methodGETfetch(/, {method: GET})credentialssame-originfetch(/, {credentials: same-origin})cachedefaultfetch(/, {cache: default})modecorsfetch(/, {mode: cors})redirectfollowfetch(/, {redirect: follow})referrerabout:clientfetch(/, {referrer: about:client})referrerPolicyfetch(/, {referrerPolicy: })integrityfetch(/, {integrity: })keepalivefalsefetch(/, {keepalive: false})原文档示例// ❌ 错误 await fetch(/, {method: GET}); // ✅ 正确 await fetch(/);// ❌ 错误 await fetch(/, {credentials: same-origin}); // ✅ 正确 await fetch(/);关于method有一个细节比较时大小写不敏感。源码isDefaultValuerules/no-unnecessary-fetch-options.js#L433-L444对method先做toUpperCase()再比较因此get、Get等写法同样会被识别并移除// ❌ 错误小写/混合大小写的 GET 也会被移除 await fetch(https://example.com, {method: get}); await fetch(new URL(url), {method: Get});需要强调默认值判定基于静态值分析。测试用例test/no-unnecessary-fetch-options.js验证了const method GET; fetch(/, {method})、fetch(/, {method:GET})、fetch(/, {method: GET})、fetch(/, {[method]: GET})等写法都会被报错而fetch(url, {method})method为未定值标识符则不会误报。触发场景三undefined与null的等价写法对于RequestInit中列出的全部合法属性名源码中的requestInitProperties集合见 rules/no-unnecessary-fetch-options.js#L39-L57共 17 个attributionReporting、body、browsingTopics、cache、credentials、duplex、headers、integrity、keepalive、method、mode、priority、redirect、referrer、referrerPolicy、signal、window显式赋值为undefined与省略等价一律移除// ❌ 错误 await fetch(url, {signal: undefined}); // ✅ 正确 await fetch(url);同样地body: null表示无请求体等价于省略也会被移除// ❌ 错误 new Request(url, {body: null}); // ✅ 正确 new Request(url);注意区分body: undefined命中属性名集合 undefined 规则和body: null专门的isStaticNull分支见 rules/no-unnecessary-fetch-options.js#L454-L459都会被移除但body: 是合法的空字符串请求体不会被移除。触发场景四空的headers当输入确定为非Request时headers的三种空值写法空对象{}、空数组[]、无参的new Headers()等价于省略对应isEmptyHeaders判定rules/no-unnecessary-fetch-options.js#L297-L313// ❌ 错误 fetch(/, {headers: {}}); fetch(/, {headers: []}); fetch(/, {headers: new Headers()});关键边界输入是否为Request决定默认值是否成立这是本规则最核心的设计点。规则文档明确指出SomeRequestInitdefaults are only equivalent when the input is known not to be an existingRequest, because omitted options inherit from the input request.当fetch()/new Request()的第一个参数本身是一个Request对象时省略的选项会继承自该输入请求而非采用规范默认值。因此与默认值相等这一判断只在输入确定不是Request时成立。源码用三态建模rules/no-unnecessary-fetch-options.js#L71-L73request输入确定是Request例如new Request(url)字面量、类型标注为Request的变量non-request输入确定不是Request字符串字面量、无表达式的模板字符串、new URL(...)、TS 类型为string/URL/String等unknown无法确定普通标识符url、无 TS 类型信息等。判定逻辑见getInputStaterules/no-unnecessary-fetch-options.js#L387-L431isUnnecessaryPropertyrules/no-unnecessary-fetch-options.js#L446-L473中的规则是无论输入状态如何属性值静态为undefined、或body为null一律移除因为继承也不会改变无值语义仅当输入为non-request空headers与等于默认值的选项才会被移除输入为request{method: GET}、{mode: cors}等默认值写法不会被移除因为它们覆盖了继承自输入请求的值是有意义的。这正是原文档最后一个示例的含义// ✅ 正确第一个参数是 Request显式 method 会覆盖继承值不能移除 await fetch(request, {method: GET});测试用例中也有大量对照验证fetch(url, {method: GET})url未知有效、fetch(request, {method: GET})有效、fetch(new Request(url, {method: POST}), {method: GET})有效而fetch(https://example.com, {method: GET})、new Request(https://example.com, {method: GET})无效。类型感知TypeScript判定当使用 TypeScript parser如typescript-eslint/parser并开启 project 服务时规则会借助类型信息深入判断。getInputTypeStaterules/no-unnecessary-fetch-options.js#L349-L385会展开联合类型 / 交叉类型若其中含Request则保守地按request处理递归取getBaseConstraintOfType与基类型对string字面量、URL、String等明确判为non-request对默认库符号isDefaultLibrarySymbol才采信其类型名避免被用户自定义的Request类干扰。测试中的typeAware用例test/no-unnecessary-fetch-options.js#L7-L14验证了declare const request: Request; fetch(request, {method: GET})有效而declare const url: string; fetch(url, {method: GET})无效、declare const input: Request | string; fetch(input, {method: GET})因含Request而保持有效不误报。自动修复注释保护与多种移除策略规则的自动修复相当精细核心目标是在不丢失注释、不引入副作用的前提下完成安全的代码变换。修复入口见getFix与getWholeOptionsFixrules/no-unnecessary-fetch-options.js#L475-L533并按优先级依次尝试整对象移除当所有属性都不必要、且对象内无注释时直接把整个 options 实参删掉。例如fetch(/, {method: GET, credentials: same-origin})会被修复为fetch(/)测试见 test/no-unnecessary-fetch-options.js#L185-L197new Request(/, {method: GET, credentials: same-origin})修复为new Request(/)。实参删除复用getArgumentRemovalRangerules/fix/remove-argument.js#L14-L44会一并处理尾随逗号、前后逗号及括号间隙。部分属性移除逐属性删除支持整行移除getPropertyLineRemovalRange或行内移除getPropertyInlineRemovalRangerules/no-unnecessary-fetch-options.js#L197-L287兜底使用通用工具removeObjectPropertyrules/fix/remove-object-property.js自动处理属性前后的逗号。仅剩一个属性时如果对象中只剩一个可移除属性但对象还有其他不可移除内容例如实参后面还有第三个参数会退化为保留空对象{}fixer.replaceText(optionsNode, {})。修复过程有严格的安全护栏isUnsafeToRemovePropertyrules/no-unnecessary-fetch-options.js#L153-L159副作用保护属性值或计算属性键包含函数调用、成员访问等潜在副作用时不自动修复。测试用例如fetch(/, {method: (sideEffect(), GET)})虽然报错但不会自动修复后置声明保护hasReferenceDeclaredAfterrules/no-unnecessary-fetch-options.js#L118-L151检测到属性值引用了声明在调用点之后的变量时拒绝移除。测试用例fetch(/, {method, credentials: same-origin}); const method GET;只移除credentials保留method因为它引用的method在调用之后才声明注释保护选项对象内部含注释、属性行内有注释、实参后有注释等场景要么跳过修复要么保留注释。例如fetch(/, {method: GET /* keep */})报错但保留注释不自动修改fetch(url, /* keep */ {})同理。此外静态值分析还会刻意绕过可能被改写的值通过 getter、Object.defineProperty、Set等可变对象派生出的值不会被当作默认值移除见测试中大量Object.defineProperty与modes.clear()用例确保修复绝不改变运行时行为。不触发的情形与限制以下写法规则不会报告值得留意第一个参数是标识符fetch(url, {method: GET})、fetch(url, {mode: cors})因为url状态未知无法证明默认值等价fetch(url, options)——options 不是对象字面量无法静态分析非全局的fetch/Request源码通过isGlobalIdentifierNamed校验rules/no-unnecessary-fetch-options.js#L596-L623const fetch () {}; fetch(url, {})、new NotRequest(url, {})等均不会误报属性名含计算键、重复键、展开符如fetch(url, {...options, method: GET})、fetch(url, {[key]: value, method: GET})时因无法确定属性名集合而跳过getObjectPropertyNamesrules/no-unnecessary-fetch-options.js#L315-L330。结语unicorn/no-unnecessary-fetch-options的价值在于把与默认值相等这种语义冗余从代码中系统性清除同时通过输入是否为Request的类型三态判定、副作用与后置声明保护、注释感知的修复策略将误报与破坏性修复降到最低。如果你已经在使用recommended预设它已经在守护你的 fetch 调用结合 TypeScript parser 使用时还能获得更精确的类型级判断。【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表