一文深入探究.js、.mjs 和.cjs 文件扩展名的区别

作者:墨池

时间:2026-10-31

浏览:102

本文详细解析Node.js中.js、.mjs和.cjs三种文件扩展名的区别。.js文件默认遵循CommonJS规范,.mjs文件强制使用ES模块,而.cjs文件在ES模块项目中用于明确兼容CommonJS。了解这些规范有助于编写高效、可维护的代码并解决模块加载问题。

文章目录

引言

在 JavaScript 开发范畴内,特别是 Node.js 场景下,开发者常接触到 .js、.mjs 以及 .cjs 三类文件后缀。尽管表面仅为后缀不同,其背后代表的模块规范与执行机制存在显著差异。厘清这些差异,对构建高效、稳健且易于维护的代码体系具有关键意义。

一、.js 文件

.js 作为 JavaScript 最普遍的后缀形式,具备极高的通用性。在 Node.js 工程实践中,若 package.json 配置文件中未定义 "type": "module" 属性,则 .js 文件默认采用 CommonJS 模块标准。

(一)导入与导出机制

CommonJS 规范通过 require() 方法实现模块引入,并利用 module.exports 或 exports 接口暴露模块内容。以文件 mathUtils.js 为例,该文件封装了基础数学运算逻辑:

// mathUtils.mjs
export function add(a, b) {
    return a + b;
}

export function subtract(a, b) {
    return a - b;
}

在调用方文件中引用该模块的代码示例如下:

const math = require('./mathUtils.js');
console.log(math.add(5, 3)); 
console.log(math.subtract(5, 3)); 

(二)特性与应用场景

CommonJS 模块采用同步加载机制,即当执行 require() 操作时,Node.js 会阻塞当前模块的执行流程,直至目标模块加载并执行完成。此机制契合服务器端开发场景,因服务端文件多存储于本地文件系统,同步加载的性能损耗在可接受范围内。在传统 Node.js 项目中,.js 文件作为 CommonJS 模块被大量应用。

二、.mjs 文件

使用 .mjs 后缀明确标识该文件为 ES 模块,严格遵循 ECMAScript 标准定义的模块规范。

(一)导入与导出机制

ES 模块借助 import 与 export 关键字管理模块的引入与输出。将前述 mathUtils.js 重构为 ES 模块格式,即命名为 mathUtils.mjs:

// mathUtils.mjs
export function add(a, b) {
    return a + b;
}

export function subtract(a, b) {
    return a - b;
}

在其他文件中引入并使用该模块的代码如下:

import { add, subtract } from './mathUtils.mjs';
console.log(add(5, 3)); 
console.log(subtract(5, 3)); 

此外,ES 模块体系支持默认导出模式,示例如下:

// person.mjs
const name = 'John';
const age = 30;
export default { name, age };

对应的引入代码为:

import person from './person.mjs';
console.log(person.name); 
console.log(person.age); 

(二)特性与应用场景

ES 模块支持静态导入与导出,这意味着在编译期即可确定模块依赖图谱,有利于代码优化与静态分析。同时,其动态导入特性提供了更为灵活的加载策略。示例如下:

async function loadModule() {
    const module = await import('./someModule.mjs');
    module.doSomething();
}

此类模块系统在浏览器前端开发及现代 Node.js 项目中应用普遍,尤其在需利用原生 ES 模块特性的场景下。

三、.cjs 文件

.cjs 后缀明确指示该文件为 CommonJS 模块。当项目整体配置为 ES 模块(通过在 package.json 中配置 "type": "module" 实现),但部分遗留代码仍需依赖 CommonJS 模块时,可将此类文件后缀重命名为 .cjs。

(一)导入与导出机制

其引入与输出方式与传统 CommonJS .js 文件一致,采用 require() 函数进行引入,通过 module.exports 或 exports 进行输出。示例如下:

// logger.cjs
const fs = require('fs');

function log(message) {
    fs.writeFileSync('log.txt', message + '\n', { flag: 'a' });
}

module.exports = { log };

在其他文件中调用该模块的代码如下:

const logger = require('./logger.cjs');
logger.log('This is a log message');

(二)特性与应用场景

在以 ES 模块为主导的项目架构中,.cjs 文件用于兼容仅支持 CommonJS 模块的旧版库或组件,保障项目运行的连续性。此外,对于兼容性要求严苛、暂不宜转换为 ES 模块的代码片段,亦可保留为 .cjs 文件形式。

四、总结

.js 文件的行为取决于 package.json 配置中的 "type" 属性,可解析为 CommonJS 或 ES 模块,具备一定灵活性,但也可能引发理解上的歧义。.mjs 文件明确标识为 ES 模块,采用 import 与 export 关键字,适用于现代 JavaScript 开发,特别是在需利用 ES 模块特性的场景。.cjs 文件则明确标识为 CommonJS 模块,主要用于在以 ES 模块为主的项目中兼容旧有库或模块。

在实际工程实践中,需依据项目需求、模块类型及与其他库的兼容性要求,合理选用 .js、.mjs 及 .cjs 文件后缀。正确运用这些后缀,不仅能提升代码的可读性与可维护性,还能确保项目在不同运行环境下的稳定性。

期望通过本文阐述,读者能深入理解这三种文件扩展名的差异,并在后续项目中灵活运用。

关于.js、.mjs 和.cjs 文件扩展名区别的文章介绍至此。如需了解更多相关.js、.mjs和.cjs文件扩展名区别内容,请查阅本站往期文章或继续浏览下方关联文章。感谢大家的支持!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章