1. 使用IIFE(立即执行函数表达式)和条件判断
// 自执行函数包裹模块代码
(function (global) {
// 判断是否为CommonJS环境
if (typeof exports === 'object' && typeof module === 'object') {
module.exports = function () {
// 模块具体实现逻辑
console.log('This is a module in CommonJS');
};
// 判断是否为ES6 Modules环境
} else if (typeof define === 'function' && define.amd) {
define([], function () {
return function () {
console.log('This is a module in AMD (used in some browsers)');
};
});
} else {
global.MyModule = function () {
console.log('This is a module in browser global scope');
};
}
})(this);
- 优点:代码简洁,能较好地兼容不同环境,在运行时通过条件判断选择合适的导出方式,性能上没有引入过多额外开销。
- 缺点:代码结构相对传统,不够现代化,对于复杂模块逻辑,这种方式组织代码可读性可能受影响。
2. 利用Babel和Webpack
- 配置Babel:在项目中安装并配置Babel,使其能将ES6 Modules语法转换为CommonJS语法。
- 安装
@babel/core
、@babel/preset - env
等相关依赖。
- 在项目根目录创建
.babelrc
文件:
{
"presets": [
[
"@babel/preset - env",
{
"targets": {
"node": "current"
}
}
]
]
}
- 配置Webpack:安装
webpack
、webpack - cli
,并创建webpack.config.js
文件。
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename:'main.js',
libraryTarget: 'umd',
library: 'MyModule'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel - loader'
}
}
]
}
};
- 优点:利用现代工具,代码可以按照ES6 Modules规范编写,语法更简洁、清晰,提升开发效率。
libraryTarget: 'umd'
可以生成通用模块定义,兼容多种环境。通过Babel转译,能确保在Node.js等不支持ES6 Modules原生的环境中运行。
- 缺点:增加了项目的配置复杂度,需要熟悉Babel和Webpack的配置,打包过程可能会带来一定的性能开销,但可通过优化配置来降低。
3. 使用动态导入(ES2020+ 提案)
async function loadModule() {
if (typeof exports === 'object' && typeof module === 'object') {
const module = await import('./myModule.cjs');
return module.default;
} else {
const module = await import('./myModule.mjs');
return module.default;
}
}
loadModule().then(module => {
// 使用模块
module();
});
- 优点:代码结构清晰,符合现代JavaScript的异步编程风格,利用动态导入能根据环境灵活加载模块,性能上按需加载可能更优。
- 缺点:依赖较新的JavaScript特性,对运行环境要求较高,兼容性不如前两种方案广泛,在不支持动态导入的环境中需要额外的polyfill。