
Rome Lint 规则 noNamespace 详解禁用 TypeScript 旧式 namespace拥抱 ES6 模块【免费下载链接】toolsUnified developer tools for JavaScript, TypeScript, and the web项目地址: https://gitcode.com/gh_mirrors/to/toolsnoNamespace是 Rome当前仓库 unified developer tools提供的一条样式类styleLint 规则用于禁止在 TypeScript 代码中使用namespace与module关键字声明命名空间。本指南基于 website/src/pages/lint/rules/noNamespace.md 展开并结合规则源码 crates/rome_js_analyze/src/analyzers/style/no_namespace.rs 与其测试用例讲解规则的判定逻辑、诊断输出、合法/非法写法以及如何在实际项目中启用、配置与抑制该规则。读完本文你将能在自己的 TypeScript 工程中准确接入这条规则并理解它背后的 AST 匹配实现原理。规则背景为什么不再推荐 namespaceTypeScript 的namespace早期称为内部模块是历史上组织代码的一种方式。随着 ES6 模块体系import/export的普及官方已不推荐继续使用 namespace原因包括namespace 属于语言层面的遗留特性社区与官方文档均建议使用 ES 模块替代ES6 模块拥有静态分析、Tree Shaking、按需加载等现代工具链能力namespace 不具备新旧代码混用会提高认知成本统一使用import/export更利于团队协作与代码演进。Rome 因此提供noNamespace规则在代码中一旦出现 namespace 声明就发出警告。该规则的设计参考了 typescript-eslint 生态中的no-namespace规则规则文档的 Source 字段注明了出处见 no_namespace.rs。规则的四个非法示例Invalid以下四种写法都会被noNamespace规则标记为违规module foo {}declare module foo {}namespace foo {}declare namespace foo {}四种写法分别是非声明形式的module、带declare的模块声明、普通namespace、带declare的命名空间声明。无论是否使用declare修饰只要以具名形式声明命名空间都会触发诊断。诊断输出示例对module foo {}的检查结果规则 ID 为lint/style/noNamespacestyle/noNamespace.js:1:1 lint/style/noNamespace ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚠ TypeScripts namespaces are an oudated way to organize code. 1 │ module foo {} │ ^^^^^^^^^^^^^ 2 │ ℹ Prefer the ES6 modules (import/export) over namespaces.主诊断消息为TypeScripts namespaces are an oudated way to organize code.该措辞为源码中的原文保留自 no_namespace.rs附带的提示note为Prefer the ES6 modules (import/export) over namespaces.诊断会精确指向module/namespace关键字的起始位置与声明整体范围例如declare module foo {}的定位起点是第 1 列的第 9 个字符即module关键字处。合法的写法Valid以下代码不会被noNamespace报错import foo from foo; export { bar };ES6 模块的import/export是推荐的替代方案完全合法。declare global {}declare global用于向全局作用域补充类型声明不属于命名空间声明合法。declare module foo {}带字符串字面量的declare module foo {}是用于声明外部模块如为无类型 npm 包补充.d.ts类型的合法用法与具名的module foo {}不同不会被该规则拦截。核心区分点规则针对的是具名的 namespace/module 声明declare global与带引号的模块声明属于合法的声明合并与模块扩充场景。源码实现规则是如何工作的规则完整的实现位于 crates/rome_js_analyze/src/analyzers/style/no_namespace.rs全文约 80 行结构非常清晰。规则声明declare_rule! { pub(crate) NoNamespace { version: 12.0.0, name: noNamespace, recommended: false, } }关键元数据见 no_namespace.rsversion: 12.0.0规则自 Rome v12.0.0 起提供name: noNamespace规则在配置与诊断中的唯一标识recommended: false非推荐non-recommended规则默认不随推荐集启用需要显式配置开启下文详述。规则核心逻辑impl Rule for NoNamespace { type Query AstTsModuleDeclaration; type State (); type Signals OptionSelf::State; type Options (); fn run(_: RuleContextSelf) - Self::Signals { Some(()) } fn diagnostic(ctx: RuleContextSelf, _: Self::State) - OptionRuleDiagnostic { ... } }实现要点no_namespace.rsQuery 类型AstTsModuleDeclaration即规则以语法树中的TsModuleDeclaration节点为匹配对象。只要 AST 中出现该节点规则就会触发run恒返回Some(())不需要额外的状态分析命中即报Options ()该规则不接受任何自定义选项诊断构建使用RuleDiagnostic::new生成主诊断并调用.note(...)追加提示信息诊断范围取自node.syntax().text_trimmed_range()即节点去除首尾空白后的完整文本范围。从源码结构看规则利用 Rome 的 AST 节点匹配机制AstTQuery实现因此无需进行语义分析属于轻量、快速、纯语法层面的规则。语法节点定义TsModuleDeclaration节点由 TypeScript 语法生成定义于 crates/rome_js_syntax/src/generated/nodes.rs 附近并被包装进AnyJsStatement、AnyJsDeclaration等联合类型。这解释了为什么module foo {}与namespace foo {}语句/声明两种形态都能被同一规则捕获。规则注册规则通过 crates/rome_js_analyze/src/analyzers/style.rs 中的pub(crate) mod no_namespace;声明模块并在该文件的规则列表中注册NoNamespace最终由生成文件 crates/rome_js_analyze/src/registry.rs 汇总到全局分析器注册表。测试用例验证规则带有完整的规格测试位于 crates/rome_js_analyze/tests/specs/style/noNamespace/invalid.ts包含 4 个非法样例module foo {}、declare module foo {}、namespace foo {}、declare namespace foo {}对应快照 invalid.ts.snap 精确记录了 4 条诊断的位置、消息文本与代码高亮范围valid.ts包含export {}、declare global {}、declare module foo {}三个合法样例并注释/* should not generate diagnostics */声明不应产生诊断对应快照 valid.ts.snap。这些用例由 crates/rome_js_analyze/tests/spec_tests.rs 驱动快照机制保证了规则行为随代码演进保持稳定。在项目中启用 noNamespace由于该规则recommended: false默认不生效需要修改rome.json配置显式开启。将规则值设为error或warn均可使其启用详见 website/src/pages/linter/index.mdx 中关于启用规则的说明{ linter: { enabled: true, rules: { style: { noNamespace: error } } } }配置说明linter.enabled必须为true否则整个 linter 不运行规则位于style分组下因此配置键路径为linter.rules.style.noNamespace设为error时违规代码会产生 error 级别诊断影响rome check的退出结果设为warn时仅输出警告可参考仓库根目录 rome.json 中已有的linter.rules.style配置写法例如其中将noNonNullAssertion显式设为off。启用后运行检查命令即可生效rome check ./src抑制Suppression与关闭规则当个别位置确实需要保留 namespace例如维护遗留代码、生成.d.ts声明时可以按行抑制诊断而不必全局关闭规则。抑制注释格式如下// rome-ignore lint/style/noNamespace: 遗留声明文件暂不迁移 declare module foo {}抑制注释的语法为rome-ignore lint/group/ruleName: explanation完整说明见 website/src/pages/linter/index.mdx 的 Ignoring Code 章节。其中lint表示抑制的是 linter 诊断/style/noNamespace可选地指定要抑制的具体规则若省略规则名如// rome-ignore lint: reason则会抑制该行全部 lint 诊断explanation必须给出抑制原因便于代码审查与后续清理。如需在配置层面彻底关闭则将该规则设为off{ linter: { rules: { style: { noNamespace: off } } } }迁移建议小结新代码一律使用 ES6 模块具名导出用export function/const/class ...按需导入用import ... from ...需要扩充全局类型时使用declare global {}而不是全局 namespace需要为外部模块补充类型时使用declare module 模块名 {}带引号这两种场景均不受noNamespace影响存量 namespace 代码建议分批迁移迁移期间可先以warn级别开启该规则配合行级rome-ignore注释逐步收敛最终切换为error强制约束。关联链接规则文档源文件规则源码实现规则测试目录Lint 规则抑制与配置说明仓库 linter 配置示例【免费下载链接】toolsUnified developer tools for JavaScript, TypeScript, and the web项目地址: https://gitcode.com/gh_mirrors/to/tools创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考