拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Biome 修复 `useNamingConvention` 误报:`declare global` 与外部模块中的 `namespace` 不再被重命名

Biome 修复useNamingConvention误报declare global与外部模块中的namespace不再被重命名【免费下载链接】biomeA toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.项目地址: https://gitcode.com/gh_mirrors/bi/biome本文以 Biome 仓库中的 changeset 变更记录.changeset/naming-convention-ambient-namespaces.md为核心剖析useNamingConvention规则针对 TypeScript ambient 声明的行为修复此前biome check --write会错误地重命名declare global或外部模块声明内的namespace本次修复使其不再报告这类声明。读者阅读后可理解该规则的忽略机制、底层作用域判定实现以及对应的测试用例并掌握升级后的正确行为。变更概览一个 patch 级别的行为修复该 changeset 声明了对biomejs/biome的patch补丁级变更修复了 GitHub issue #11566 对应的问题useNamingConvention不再报告在declare global内部或外部模块声明external module declaration内部声明的namespace。changeset 原文给出的触发场景如下export {} declare global { // no longer renamed to Jsx namespace JSX {} }修复前useNamingConvention会对namespace JSX报告诊断并且由于该规则附带安全修复safe fix运行biome check --write会将其自动重命名为Jsx修复后这类声明被完整跳过不再产生任何诊断或自动改写。规则背景useNamingConvention为何会管到 namespaceuseNamingConvention是 Biome 的 lint 规则用于强制整个代码库遵循命名约定Enforce naming conventions for everything across a codebase声明于 crates/biome_js_analyze/src/lint/style/use_naming_convention.rs。它按声明种类Kind施加默认约定其中与本次修复直接相关的是类、枚举、接口、类型别名、类型参数 →PascalCase变量 /const/var/let→camelCase或PascalCase全局const/var额外允许CONSTANT_CASE函数、export namespace、import namespace、namespace、namespace类成员、函数参数 →camelCase或PascalCase默认约定映射见 use_naming_convention.rsKind::Namespace等被映射为Case::Camel | Case::Pascal。这正是namespace JSX会被报告的原因——JSX是全大写的缩写形式既不是camelCase也不是PascalCase在默认strictCase: true下连续大写字符不被允许因而命中诊断并被建议改名为Jsx。然而规则文档中本就声明了若干**总是被忽略always ignored**的声明位置见 use_naming_convention.rs其中包括不是标识符的成员名如计算属性名具名导入named imports解构对象属性标记了override的类成员外部 TypeScript 模块内部的声明declare module myExternalModule { export interface my_INTERFACE {} }全局声明declare global内部的声明declare global { interface HTMLElement {} }本次 changeset 修复的实质就是让namespace声明在这两个应被忽略的位置上真正生效与文档声明的行为对齐并消除了原本不必要的自动重命名。源码实现scope_from_declaration如何跳过 ambient 声明修复的核心位于use_naming_convention.rs中的作用域判定辅助函数scope_from_declarationuse_naming_convention.rs/// Returns the scope of node or None if the scope cannot be determined or /// if the scope is an external module. fn scope_from_declaration(node: AnyJsBindingDeclaration) - OptionScope { let control_flow_root node.syntax().ancestors().skip(1).find(|x| { AnyJsControlFlowRoot::can_cast(x.kind()) || x.kind() JsSyntaxKind::TS_DECLARATION_MODULE || x.kind() JsSyntaxKind::TS_EXTERNAL_MODULE_DECLARATION || x.kind() JsSyntaxKind::TS_GLOBAL_DECLARATION })?; match control_flow_root.kind() { JsSyntaxKind::JS_MODULE | JsSyntaxKind::JS_SCRIPT | JsSyntaxKind::TS_DECLARATION_MODULE | JsSyntaxKind::TS_MODULE_DECLARATION Some(Scope::Global), // Ignore declarations in external module declaration and global declarations. JsSyntaxKind::TS_EXTERNAL_MODULE_DECLARATION | JsSyntaxKind::TS_GLOBAL_DECLARATION None, _ Some(Scope::Any), } }其工作方式可以拆解为三步向上查找控制流根节点从声明节点沿语法树向上跳过自身寻找最近的控制流根或三类特殊的 TypeScript 声明节点——TS_DECLARATION_MODULEdeclare module、TS_EXTERNAL_MODULE_DECLARATION外部模块声明、TS_GLOBAL_DECLARATIONdeclare global。判定作用域若根节点是普通模块JS_MODULE、脚本JS_SCRIPT或declare module/命名空间模块声明则返回Scope::Global若根节点是TS_EXTERNAL_MODULE_DECLARATION或TS_GLOBAL_DECLARATION则返回None。None即跳过调用方使用?运算符如 use_naming_convention.rs 中scope_from_declaration(decl)?的写法一旦返回None该声明就不会生成选择器Selector自然也不会产生任何诊断与修复动作。值得注意的是JS_MODULE、JS_SCRIPT、TS_DECLARATION_MODULE、TS_MODULE_DECLARATION返回Scope::Global意味着位于这些作用域中的全局变量仍会被正常检查Scope枚举本身定义于 biome_rule_options/src/use_naming_convention.rs用于支持selector.scope配置只有declare global与外部模块声明这两个 ambient 位置被明确排除。从实现上看这正是本次 changeset 所描述修复的落地位置。测试用例验证spec 测试锁定的行为Biome 为本次修复补充了对应的 spec 测试位于 crates/biome_js_analyze/tests/specs/style/useNamingConvention/validGlobalNamespace.ts与 changeset 示例完全一致断言不应产生诊断/* should not generate diagnostics */export {} declare global { namespace JSX {} }validExternalModule.tsdeclare module myExternalModule { ... }内的声明不应产生诊断。validExternalModuleNamespace.ts外部模块内部的 namespace 声明同样被忽略。validInterfaceOverload.tsdeclare global内的接口重载不被报告。这些用例的输入文件与.snap快照如validGlobalNamespace.ts.snap一一对应任何回归例如再次对namespace JSX报告或给出重命名建议都会导致 spec 测试失败从而从测试层面锁定了该修复行为。对用户的影响与升级建议如果你此前在项目中依赖useNamingConvention并在declare global/ 外部模块声明中放置了namespace例如常见的declare global { namespace JSX {} }写法用于为 JSX 命名空间补充类型升级前biome check会报告这些namespace名称不符合camelCase/PascalCasebiome check --write还会执行安全修复将其重命名为Jsx之类的名称导致无谓的源码改动甚至可能影响与第三方类型声明的匹配。升级后包含该 patch 的版本这些声明被完全忽略不再产生诊断也不会被自动重命名与规则文档中总是忽略的说明保持一致。验证方法很简单将上述validGlobalNamespace.ts示例写入项目并运行biome check应看到 0 个相关诊断运行biome check --write时文件内容应保持不变。由于这是 patch 级别的修复升级biomejs/biome到包含该变更的版本即可获得无需调整任何biome.json配置——该行为修复对默认配置和自定义conventions均生效因为跳过逻辑发生在选择器Selector生成阶段早于任何约定匹配。【免费下载链接】biomeA toolchain for web projects, aimed to provide functionalities to maintain them. Biome offers formatter and linter, usable via CLI and LSP.项目地址: https://gitcode.com/gh_mirrors/bi/biome创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门