这段时间在开发用nodejs写的后端,是个很老的项目,node版本是10.X.X。。。习惯性的用import导入模块,发现项目报错才反应过来
想到面试的时候也经常会被问到这个问题,属于典型的前端八股文范畴,正好遇到了,就稍微整理一下吧,自己的理解,不对的地方请大佬指正
1. CommonJS模块
- 定义:CommonJS是一种用于服务器端JavaScript的模块规范,最初被应用在Node.js中。它允许将一个大的程序拆分成互相依赖的小文件。
示例:
// 导出CommonJS模块
module.exports = {
sum: function(a, b) {
return a + b;
}
};
// 导入CommonJS模块
const math = require('./math');
console.log(math.sum(2, 3)); // 输出:5
2. ES模块
- 定义:ES模块(ECMAScript模块)是JavaScript官方的标准模块系统,被引入在ECMAScript 2015(ES6)中。它旨在在浏览器和服务器端JavaScript中通用。
示例:
// 导出ES模块
export const sum = (a, b) => a + b;
// 导入ES模块
import { sum } from './math.js';
console.log(sum(2, 3)); // 输出:5
3. 主要区别
-
语法:
- CommonJS使用
require()
来导入模块,module.exports
或exports
来导出模块。 - ES模块使用
import
和export
语句来导入和导出模块。
- CommonJS使用
-
模块加载:
- CommonJS模块是运行时同步加载的。
- ES模块是静态的,允许编译时静态分析,并且可以异步加载。
-
模块解析:
- CommonJS模块的输出是一个值的拷贝。
- ES模块的输出是值的引用,且不允许修改导入的模块。
-
跨平台兼容性:
- CommonJS主要用于Node.js环境。
- ES模块旨在成为跨平台的解决方案,适用于现代浏览器和最新版本的Node.js。
-
性能:
- CommonJS由于同步加载,可能会导致性能问题,特别是在处理大型依赖树时。
- ES模块由于支持静态分析和异步加载,可以更好地进行代码拆分和懒加载,有助于提高性能。
4. 兼容性和转换
- Node.js:较新版本的Node.js支持ES模块,但需要特定的文件扩展名(如
.mjs
)或配置。 - 转换工具:存在如Babel或Webpack这样的工具,它们可以将ES模块转换为CommonJS模块,以便在不支持ES模块的环境中使用。
示例:
- 原始ES模块代码:
export const sum = (a, b) => a + b;
这行代码使用ES模块语法导出一个名为 sum
的函数。
- 经过Babel转换后的CommonJS代码:
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.sum = void 0;
var sum = function sum(a, b) {
return a + b;
};
Object.defineProperty
用于安全地导出模块属性。exports.sum = void 0;
初始化 sum
函数的导出,确保它是可写的、可配置的,并且在导出时不会被修改。var sum = function sum(a, b) { return a + b; };
是 sum
函数的CommonJS版本。
原本只能在支持ES模块的环境中运行的代码现在可以在任何支持CommonJS模块的环境中运行