.mjs 文件其实和你熟悉的 .py 文件一样,都是纯文本格式的代码文件。它的特别之处在于,它是专门给 Node.js 环境 使用的 JavaScript 模块文件 ,用来明确标识代码遵循的是 ECMAScript 模块 (ES Module) 标准。
和你想必知道的 .py 文件是 Python 代码的标识类似,.mjs 就是 "JavaScript 的 ES 模块文件" 这个特定身份的标识。
为什么要有 .mjs 文件?
Node.js 默认使用一套名为 CommonJS (CJS) 的模块系统(也就是我们常见的 require() 和 module.exports 语法)。后来 JavaScript 推出了官方的、更现代化的模块标准------ES Module (ESM)(使用 import 和 export 语法)。
问题在于,这两种模块系统在加载方式、语法上都不同,直接混用会出问题。为了在不破坏旧有项目的前提下,让 Node.js 能明确区分并正确加载新标准的模块,社区引入了 .mjs 这个扩展名。
.mjs 和常规的 .js 文件有什么区别?
最关键的区别在于 Node.js 会如何处理它们:
| 特性 | .mjs 文件 |
.js 文件 (在 Node.js 中) |
|---|---|---|
| 模块系统 | 固定为 ES Module | 取决于 package.json 中的 "type" 字段。默认是 CommonJS。 |
| 核心语法 | 使用 import / export |
可能使用 require() / module.exports,也可能使用 import / export(如果项目配置为模块)。 |
| 加载方式 | 异步加载 | 同步加载 (CommonJS 时) |
| 核心区别 | 文件扩展名本身明确声明了其模块类型,消除了歧义。 | 文件类型不明确,需要依赖外部配置。 |
一个直观的理解方式是:
.mjs强制要求你使用import语法,而.js在 Node.js 中默认情况下则使用require语法。
关键使用规则
- 必须使用
import:在.mjs文件中,只能使用import和export。如果尝试在里面写require(),会直接报错。 - 不能
require('.mjs'):反过来,在一个 CommonJS 模块(通常是.js文件)里,也无法通过require()来加载一个.mjs文件。
总结一下,.mjs 是 Node.js 世界里为了解决新旧两种模块系统共存问题而生的一个"身份标签",它让 JavaScript 代码的模块类型变得清晰可控。