typescript/no-require-imports 限制
功能说明
禁止使用 CommonJS require 调用。
为什么这是不好的?
尽管 require 在 Node.js 及旧版 JavaScript 环境中是可行的,但在现代 JavaScript 开发中,它通常被认为不如 ES 模块(import)理想,原因如下:
静态与动态:
require是一个运行时函数。它在代码执行时才运行,这意味着缺少模块或路径错误只有在运行时才会被发现。而 ES 模块(import)是静态导入。其解析和潜在错误会在编译或打包阶段检查,使开发过程中更容易发现问题。代码组织与可读性:
require语句分散在代码各处,可能使快速识别某个模块的依赖变得困难。而import语句通常集中放在文件顶部,提升了代码的组织性和可读性。树摇(Tree Shaking)与优化:现代打包工具如 Webpack 和 Rollup 使用树摇来移除最终包中的未使用代码。树摇在使用 ES 模块时效果更好,因为其依赖关系是静态且显式声明的。
require使得打包工具难以准确识别并移除未使用的代码,导致包体积更大、加载更慢。循环依赖处理:处理循环依赖(例如模块 A 导入模块 B,而模块 B 又导入模块 A)在
require中要困难得多。而通过声明式语法和动态导入(import()),ES 模块提供了更好的机制来处理循环导入以及异步加载。可维护性与重构:更改模块名称或路径时,使用 ES 模块更加简单,因为更改是直接声明的,编译器或打包工具可以立即捕获错误。而使用
require时,你可能需要追踪所有针对特定模块的require语句,这使得重构更容易出错。现代 JavaScript 标准:
import是现代 JavaScript 中导入模块的标准方式,符合当前最佳实践和语言规范。使用require需要额外的构建步骤或工具将其转换为浏览器或现代 JavaScript 环境可理解的格式。错误处理:通过动态导入搭配
try...catch块,ES 模块提供了一种更结构化的方式来处理模块加载过程中的错误,从而增强了错误管理能力。而require的错误处理则相对不可预测。
综上所述,虽然 require 可以工作,但考虑到静态分析、更优的打包效果、更好的代码组织以及更易维护性,使用 ES 模块作为现代 JavaScript 项目的模块导入方式是首选。
示例
本规则的错误代码示例:
const lib1 = require("lib1");
const { lib2 } = require("lib2");
import lib3 = require("lib3");本规则的正确代码示例:
import * as lib1 from "lib1";
import { lib2 } from "lib2";
import * as lib3 from "lib3";配置
此规则接受一个包含以下属性的配置对象:
allow
type: string[]
default: []
这些字符串将被编译为带有 u 标志的正则表达式,并用于测试导入路径。 常见用例是允许导入 package.json。这是因为 package.json 通常位于 TypeScript 根目录之外,因此静态导入会导致根目录冲突,尤其是在启用 resolveJsonModule 时。 你也可以用它来允许导入任意 JSON,如果你的环境不支持 JSON 模块,或者用于其他无法使用 import 语句的情况。
当配置为 { allow: ['/package\\.json$'] } 时:
本规则的正确代码示例:
console.log(require("../package.json").version);allowAsImport
type: boolean
default: false
设置为 true 时,import ... = require(...) 声明不会被报告。 这在使用某些需要严格 CommonJS 互操作语义的模块选项时非常有用。
当设置为 true 时:
本规则的错误代码示例:
var foo = require("foo");
const foo = require("foo");
let foo = require("foo");本规则的正确代码示例:
import foo = require("foo");
import foo from "foo";如何使用
要通过配置文件或 CLI 启用此规则,可以使用:
{
"rules": {
"typescript/no-require-imports": "error"
}
}oxlint --deny typescript/no-require-imports