nodejs引用(import、require)的一些小知识

nodejs引用(import、require)的一些小知识
最新回答
朕射你无罪

2026-10-22 23:04:18

在Node.js中,当尝试读取脚本文件时,无论是通过Node.js引擎还是浏览器,都会先决定读取方式,然后直接读取文件,而不会基于内容或元数据来判断文件格式。如果实际文件类型与预期不符,系统会直接报错。这种读取方式确保了系统的高效性和一致性。

在CommonJS环境中,可以通过`import()`函数来引用ES模块(ESM)文件,但返回的将是Promise对象。而使用`require()`函数引用ESM文件时,会抛出`ERR_REQUIRE_ESM`错误。为了解决这一问题,可以借助`fix-esm`包将ESM文件动态转换为CommonJS(CJS)格式,但这种解决方式并不能完全解决`import.meta`相关问题。

总的来说,建议避免使用CommonJS环境,大多数开发者会利用Webpack等打包工具将其转换为更现代的模块系统。对于少数不使用打包工具的开发者,他们通常能够熟练解决这类问题。

在ES模块环境下,`require()`函数已不再可用,仅能通过`import`语句来引用ESM或CJS文件。Node.js提供了一个名为`module.createRequire()`的函数,允许开发者创建自定义的`require`函数。引用CJS文件时,通常需要使用`import def from 'xxx'`的形式,并确保正确引用`def.default.xxx`。对于TypeScript开发者,开启`esModuleInterop`功能可以解决部分包实现错误导致的引用问题,尽管这可能需要对部分代码进行调整。

从Node.js 16版本开始,`package.json`文件中的`exports`字段成为默认行为,允许开发者实现同一包在导入、要求和浏览器引用时引用不同的文件。然而,TypeScript默认不解析`exports`字段,需要通过设置`resolvePackageJsonExports`选项来启用解析功能,以实现更佳的集成体验。

值得注意的是,对于模块文件的扩展名,过去在Node.js中存在不一致的处理方式。现在,从Node.js 16版本开始,系统将更严格地遵循文件名,即`import "./a"`将直接报错,除非文件或文件夹确实存在。这种更简洁的文件引用方式旨在提高开发效率和一致性,但希望这种规范能尽快在社区中普及。