十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

eslint-plugin-unicorn `import-style` 规则完全指南:按模块强制执行统一的 import 风格

eslint-plugin-unicorn `import-style` 规则完全指南:按模块强制执行统一的 import 风格 eslint-plugin-unicornimport-style规则完全指南按模块强制执行统一的 import 风格【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn本篇技术指南围绕 eslint-plugin-unicorn 的import-style规则展开系统讲解其 4 种导入风格、node:协议匹配机制、styles等全部 6 个配置项并结合 规则源码 与 测试用例 从源码级剖析其判定逻辑与边界行为。读完你将能够独立完成规则配置、理解报错含义并能在自己的 ESLint 项目中落地一套按模块差异化的导入风格规范。规则背景为什么需要按模块区分导入风格在实际项目中不同模块的最佳导入方式往往不同有些模块包含大量彼此无关的函数例如 Node.js 的utilpromisify、callbackify、inspect……此时强制使用解构式命名导入named import反而更利于 tree-shaking 与按需使用有些模块内部函数高度相似、几乎都会被用到例如pathjoin、resolve、dirname……此时默认导入default import更简洁统一。import-style正是为此而生它允许你为每个模块单独指定允许的导入风格对不在配置范围内的模块不做任何限制。该规则在项目中的地位它属于 eslint-plugin-unicorn 的众多规则之一见 规则注册文件meta.docs.recommended标记为unopinionated源码 rules/import-style.js#L398因此同时被recommended与unopinionated两套预设配置启用对应 readme 规则表中的 ✅ ☑️ 标记见 readme.md。规则类型为problem意味着它报告的是代码中确实存在的风格不一致问题。适用前提本规则基于 JavaScript AST 静态分析默认仅启用js/js语言见 rules/import-style.js#L403TypeScript 场景下对import type有特殊处理详见后文。需要 ESLint 新版 APIcontext.on支持的运行环境。规则定义的 4 种导入风格规则将导入方式抽象为 4 种风格每种风格同时覆盖 ESM 与 CommonJS 两种写法风格ESM 写法CommonJS 写法unassignedimport foorequire(foo)defaultimport path from pathconst path require(path)含const {default: path} require(path)namespaceimport * as path from pathconst path require(path)整对象赋值namedimport {inspect} from utilconst {inspect} require(util)需要特别说明的是default与namespace在require语境下的重叠由于require无法预先判断目标模块是编译后的 ES Module带default键还是 CommonJS 模块源码 rules/import-style.js#L193-L200 中做了一次放宽处理——当某模块仅允许default时const path require(path)这种 namespace 式赋值同样被视为合法。测试中const x require(default)被判定为 valid 即印证了这一点test/import-style.js#L121。基础示例默认样式下的检查行为// ❌ util 默认只允许 named 导入 const util require(node:util); // ✅ const {promisify} require(node:util);// ❌ 默认导入 util 被禁止 import util from node:util; // ❌ 命名空间导入 util 同样被禁止 import * as util from node:util; // ✅ import {promisify} from node:util;// ❌ path 默认只允许 default 导入命名空间导入被禁止 import * as path from node:path; // ✅ import path from node:path;对应到测试用例import util from node:util、import * as util from node:util、const util require(node:util)、require(node:util)等均为 invalid而import {inspect} from node:util、const {inspect} require(node:util)、import path from node:path等均为 valid见 test/import-style.js#L166-L197 与 test/import-style.js#L717-L760。未配置的模块如node:fs、node:unknown不受影响import fs from node:fs、import * as fs from node:fs、import {readFile} from node:fs均合法test/import-style.js#L252-L297。默认样式defaultStyles内置默认样式在源码中以defaultStyles常量定义rules/import-style.js#L128-L138仅覆盖 3 个模块chalk—— 仅允许default导入path—— 仅允许default导入util—— 仅允许named导入规则只对出现在styles配置与默认样式中的模块生效其余导入一概不受影响。node:协议匹配机制带node:协议的导入会剥离协议前缀后再匹配样式node:util与util使用同一套样式配置时按裸模块名util、path书写即可。这一机制由getModuleStyleName函数实现rules/import-style.js#L122-L125模块名以node:开头时截掉该前缀作为查找键。测试也验证了继承行为为util配置{default: true}后node:util变为允许named or defaulttest/import-style.js#L801-L821若同时显式声明{default: true, named: false}则node:util仅允许defaulttest/import-style.js#L822-L844而require(ut il)、require(node: util)这类非常量字符串也能被识别常量折叠后匹配见 test/import-style.js#L751-L760。Options 完整配置指南styles类型object。用于按模块扩展或收窄默认导入样式。每个模块的值既可以是false完全解除限制也可以是形如{named: true}的布尔对象。示例以下配置解除了util的全部限制同时为path额外开放named默认default仍然有效unicorn/import-style: [ error, { styles: { util: false, path: { named: true, }, }, }, ]几点重要语义值为false表示任意风格皆可测试中styles: {util: false}后import util from node:util、import * as util2 from node:util、import {foo} from node:util全部合法test/import-style.js#L309-L322。布尔对象中显式false的键会被合并覆盖styles: {util: {named: false}}会覆盖默认的{named: true}结果是 util 无任何允许风格但不会被视为禁用模块而报 banned 错误而是直接放行test/import-style.js#L323-L337。请勿将某模块的全部风格设为false这会使该模块进入banned状态报出importStyleBanned错误All import styles are disabled for module ... Use theno-restricted-importsrule to disallow a module.。该判定由源码中bannedModules集合完成rules/import-style.js#L160-L164建议改用 ESLint 自带的no-restricted-imports规则彻底禁用某个模块。样式合并规则开启extendDefaultStyles时用户配置与默认样式按默认样式 → 用户配置顺序浅合并rules/import-style.js#L155-L158用户可打开默认未开放的风格也可显式关闭默认已开放的风格。被允许的多种风格在报错信息中通过Intl.ListFormat以英文析取连词展示例如allowedStyles: named, namespace, or default见 test/import-style.js#L795。extendDefaultStyles类型boolean默认true。传入extendDefaultStyles: false可完全抛弃默认样式表仅使用styles中显式配置的内容。源码中当该值为false时styles不再与defaultStyles合并rules/import-style.js#L155-L158。典型场景团队想从头自定义全部模块样式不希望被chalk/path/util的默认规则干扰。checkImport类型boolean默认true。传入checkImport: false可完全关闭对静态 import 语句的检查import ... from foo与import foo。对应源码中的ImportDeclaration监听器rules/import-style.js#L218-L225。测试中import chalk在checkImport: false下为 validtest/import-style.js#L206-L210。checkDynamicImport类型boolean默认true。传入checkDynamicImport: false可完全关闭对动态导入await import(foo)及裸import(foo)的检查。对应ImportExpression与VariableDeclarator监听器rules/import-style.js#L227-L259。动态导入的样式判定规则裸import(foo)视为unassigned风格const {x} await import(foo)视为namedconst {default: x} await import(foo)视为defaultconst x await import(foo)与const [x] await import(foo)视为namespace对应 getActualAssignmentTargetImportStyles 的解析逻辑测试见 test/import-style.js#L632-L640。测试中const {red} await import(chalk)在checkDynamicImport: false下为 validtest/import-style.js#L212-L220。checkExportFrom类型boolean默认false。传入checkExportFrom: true可开启对export ... from foo语句的检查默认关闭。对应ExportAllDeclaration与ExportNamedDeclaration监听器rules/import-style.js#L261-L281。判定规则export * from foo视为namespace风格export {x} from foo视为namedexport {default} from foo视为default。不含from的纯export {foo}不会触发检查test/import-style.js#L160-L163。checkRequire类型boolean默认true。传入checkRequire: false可完全关闭对require调用的检查。对应CallExpression与VariableDeclarator监听器rules/import-style.js#L283-L323。规则只识别单参数、非可选链的require(...)调用且要求其处于表达式语句或变量声明初始化位置require(1, 2, 3)、require(variable)非常量参数、const x require(unassigned).x等均不会被检查test/import-style.js#L299-L302。非空的数组解构const [x] require(foo)不被识别为任何风格同样跳过检查。报错信息与类型检查TypeScript特例规则定义了两条消息rules/import-style.js#L4-L9importStyleUse {{allowedStyles}} import for module{{moduleName}}.importStyleBannedAll import styles are disabled for module{{moduleName}}. Use theno-restricted-importsrule to disallow a module.TypeScript 场景下纯类型导入不受影响import type chalk from chalk、import type {x} from named、import {type ChalkInstance} from chalk均不报错test/import-style.js#L848-L870因为源码对importKind type及 type 修饰的 specifier 直接跳过rules/import-style.js#L13-L16 与 rules/import-style.js#L38-L40。混合导入按运行时代码判定import {type ChalkInstance, red} from chalk因存在非 type 的red而按 named 判定最终报default错误test/import-style.js#L872-L882。banned 模块的类型导入同样报错import type {Foo} from banned与import {type Foo} from banned都会触发importStyleBannedtest/import-style.js#L883-L902。规则 Schema 与配置校验规则的配置项定义于 JSON Schemarules/import-style.js#L326-L387可作为编写配置时的约束参考选项为单元素数组元素为对象且不允许额外属性additionalProperties: false共 6 个布尔/对象字段styles的值类型通过definitions.styles定义为false或布尔对象booleanObject其属性值均为boolean全部选项都有默认值兜底defaultOptions: [{}]意味着不传任何参数时规则以默认样式表 全量检查除checkExportFrom外运行。推荐配置推荐的完整启用示例将以下配置加入你的 ESLint 配置文件即可启用该规则并覆盖全部常用选项unicorn/import-style: [ error, { styles: { util: false, // 取消对 util 的默认 named 限制 path: { named: true, // path 除 default 外额外允许 named }, node:fs: { default: true, // 新增模块node:fs 仅允许默认导入注意 node: 前缀按裸名匹配亦可 }, }, extendDefaultStyles: true, checkImport: true, checkDynamicImport: true, checkExportFrom: true, // 如需一并检查 export ... from checkRequire: true, }, ]如果你正在使用本仓库自带的recommended预设见 configs/flat-config-base.js 及 readme.md该规则已默认启用、开箱即用此时只需要按需通过styles扩展模块范围即可。若你的代码库风格与默认预设冲突可使用extendDefaultStyles: false完全接管样式表实现团队自定义的导入规范。小结import-style通过模块名 → 允许风格集合的映射模型把散落各处的导入风格约束收敛为可配置、可解释、可测试的规则默认样式覆盖chalk/path/util三个高频模块node:协议自动归一化匹配6 个开关分别控制 import、动态 import、export-from、require 四类语法节点的检查并完整支持 TypeScript 类型导入豁免。理解其判定逻辑后你既可以直接使用默认行为也可以通过styles与各开关精细定制属于自己的导入规范。【免费下载链接】eslint-plugin-unicornMore than 300 powerful ESLint rules项目地址: https://gitcode.com/GitHub_Trending/es/eslint-plugin-unicorn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表