在Node.js中使用ES Module时,所有Node包能否用统一import语法导入?
在Node.js ESM中导入模块的语法差异说明
核心结论
并非所有Node包都能通过同一种import语法导入,导入方式取决于模块的格式(ESM/CommonJS)以及它的导出方式。
分场景说明
1. node_modules中的第三方包
第三方包分为ESM和CommonJS(CJS)两种格式,导入逻辑不同:
- ESM格式的包:
- 如果包提供了默认导出,用
import 变量名 from '包名',比如axios、express-session - 如果包只有命名导出或无默认导出,用
import * as 变量名 from '包名',比如@azure/msal-node;也可以按需导入指定成员:import { 成员名 } from '包名' - 判断依据:查看包根目录的package.json,若
type字段为module,或exports字段明确指定ESM入口,则为ESM包
- 如果包提供了默认导出,用
- CJS格式的包:
- Node会自动兼容CJS到ESM,此时CJS的
module.exports会被映射为ESM的默认导出,因此用import 变量名 from '包名'就能获取包的核心导出内容,比如express - 如果需要获取CJS导出的所有命名成员,也可以用
import * as 变量名 from '包名',此时变量名.default对应原module.exports,其他属性对应CJS的exports.xxx
- Node会自动兼容CJS到ESM,此时CJS的
2. 自定义模块(node_modules外)
- 自己编写的ESM模块:
- 文件后缀为
.mjs,或所在目录的package.json设置type: module时,模块为ESM格式 - 默认导出用
import 变量名 from './模块路径.js',命名导出用import { 成员名 } from './模块路径.js',也可整体导入import * as 变量名 from './模块路径.js'
- 文件后缀为
- 自己编写的CJS模块:
- 文件后缀为
.cjs,或所在目录的package.json设置type: commonjs时,模块为CJS格式 - 导入方式与第三方CJS包一致,用
import 变量名 from './模块路径.cjs'即可获取module.exports的内容
- 文件后缀为
3. Node内置模块
- 两种导入语法都支持:带
node:前缀的规范写法(import fs from 'node:fs')和不带前缀的写法(import fs from 'fs') - 带
node:前缀能明确区分内置模块与第三方包,避免命名冲突,推荐使用
实用技巧
如果遇到文档未说明导入方式的包,优先尝试import 变量名 from '包名':
- 若运行正常,说明包有默认导出(无论是ESM还是兼容后的CJS)
- 若报错提示找不到默认导出,再换成
import * as 变量名 from '包名',打印变量名查看结构,就能明确需要导入的成员
内容的提问来源于stack exchange,提问作者user1063287
相关产品推荐
相关产品推荐

