返回

不再迷茫,轻松解决 require() 不支持 ES 模块问题

前端

解决“错误[ERR_REQUIRE_ESM]:不支持ES模块的require()”的多种方法

在JavaScript的世界里,模块系统扮演着至关重要的角色,它能将代码组织成独立的模块,便于复用和维护。CommonJS和ES模块是两种常见的模块系统,其中CommonJS广泛应用于Node.js服务器端开发,而ES模块则在浏览器端和一些现代化的Node.js应用中崭露头角。

错误的根源:require()的局限性

当你尝试在Node.js中使用require()加载ES模块时,可能会遇到“错误[ERR_REQUIRE_ESM]:不支持ES模块的require()”的错误。这是因为require()函数在默认情况下只支持CommonJS模块。ES模块具有不同的语法和加载机制,因此不能直接用require()加载。

化繁为简:多种解决方案

1. 修改文件扩展名

一个简单的方法是将ES模块文件的扩展名从.js改为.mjs。这样,Node.js会将该文件识别为ES模块,并用适当的加载器加载。

2. 使用动态导入

动态导入是ES模块中的新特性,允许你在运行时加载模块。可以使用import()函数动态导入ES模块,如下所示:

import('./module.mjs').then((module) => {
  // 使用模块
});

3. 使用模块加载器

如果你希望在Node.js中加载ES模块而又不修改文件扩展名或使用动态导入,可以使用模块加载器。模块加载器可以将ES模块转换为CommonJS模块,使其能被require()加载。

常用的模块加载器包括:

  • Babel
  • TypeScript
  • webpack
  • Rollup
  • Parcel
  • Vite

可以根据需要选择合适的模块加载器。

小提示:实战技巧

  1. 使用Babel将ES模块转换为CommonJS模块

Babel是一个流行的JavaScript编译器,可以将ES模块代码转换为CommonJS模块代码。可以在package.json中添加如下配置:

{
  "babel": {
    "presets": ["@babel/preset-env"]
  }
}
  1. 使用TypeScript编译ES模块

TypeScript是一个超集JavaScript的语言,支持ES模块语法。可以将TypeScript代码编译为CommonJS模块代码:

// module.ts
export const message = 'Hello, world!';

// tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs"
  }
}

常见问题解答

  1. 为什么Node.js不支持开箱即用的ES模块?

因为CommonJS模块系统已经存在了更长的时间,并且在Node.js生态系统中得到了广泛的使用。ES模块是一种较新的规范,Node.js社区仍在过渡到对它的支持。

  1. 我应该使用哪种解决方案?

取决于具体情况。如果只需要加载少数ES模块,可以使用动态导入或模块加载器。如果需要在项目中广泛使用ES模块,可以使用Babel或TypeScript将其编译为CommonJS模块。

  1. 在哪些情况下需要使用模块加载器?

当需要在Node.js中加载ES模块而又不修改文件扩展名或使用动态导入时,需要使用模块加载器。

  1. 模块加载器有哪些优点?

模块加载器可以无缝加载ES模块,而无需修改代码或使用其他技术。它们还可以提供额外的功能,如代码分割和热模块替换。

  1. 模块加载器有哪些缺点?

模块加载器可能会增加项目的复杂性和构建时间。它们还可能与某些库和工具不兼容。