写过前端代码大概率听说过amd
cmd
umd
commonjs
esm
这些名词, 想当初我第一次看到这些的时候, 人都麻了, 都是些啥啊. 后来我知道了, 这些都是js的模块规范.
AMD全称是Async Module Definition
异步模块定义
RequireJs
是AMD模块规范的一个具体实现.
AMD中定义一个计算器模块calculator
, 这个模块依赖另一个名为math
的模块
calculator.js
define('calculator', ['math'], function(math) {
return {
add: function(left, right) { return math.add(left, right) },
subtract: function(left, right) { return math.subtract(left, right) }
}
})
使用刚才定义的calculator
模块
main.js
require('calculator', function(calculator) {
console.log('1 + 1 = ' + calculator.add(1, 1));
console.log('2 - 2 = ' + calculator.subtract(2, 1));
})
CMD全称是Common Module Definition
即通用模块定义,. 像AMD
与RequireJs
关系一样, 与CMD
规范绑定的是sea.js
在定义模块方面, CMD
和AMD
一样通过define
函数来定义模块; 两者的主要区别在于对依赖的加载上, CMD
中不需要在define
的参数中直接声明需要用到的模块
还是以声明calculator
模块为例
calculator.js
define('calculator', function(require, exports) {
var math = require('math');
exports.add = function(left, right) { return math.add(left, right) };
exports.subtract = function(left, right) { return math.subtract(left, right) };
})
可以看到calculator
模块所的依赖的math
模块没有在define
函数的参数中进行声明, 而是通过require('math')
来引入的
使用calculator
模块
seajs.use(['calculator'], function(calculator) {
console.log('1 + 1 = ' + calculator.add(1, 1));
console.log('2 - 2 = ' + calculator.subtract(2, 1));
})
commonjs - Node中使用的模块规范
定义math
模块
math.js
module.exports = {
add: function(left, right) {
return left + right;
},
subtract: function(left, right) {
return left - right;
}
}
使用刚才定义的math
模块, 并再定义一个calculator
模块
calculator.js
const math = require('./math.js');
module.exports = {
add: math.add
}
amd
cmd
通常只能在浏览器中使用, commonjs
只能在服务端(Node)环境下使用, 这样子搞会导致我们基于其中某一种模块规范写的js模块无法在服务端和浏览器端进行复用. umd解决了这个问题, 它兼容并包, 使得使用此规范写的js模块既可以在浏览器环境下使用, 也可以在Node(服务端)环境中用
(function (root, factory) {
if (typeof exports === 'object' && typeof module === 'object')
// commonjs
module.exports = factory()
else if (typeof define === 'function' && define.amd)
// amd
define([], factory)
else if (typeof exports === 'object')
// commonjs
exports['math'] = factory()
else
// 全局对象, 浏览器中是 window
root['math'] = factory()
})(this, function() {
return { add: function(left, right) { return left + right; } }
})
esm - ES6模块规范
使用import
导入模块, 通过export
导出模块
math.js
export { add: (left, right) => left + right; }
点击此处查看代码
import { add } from './math.js';
console.log('1 + 1 = ' + add(1, 1));
amd, cmd已经成为了过去式(个人感觉), 现在常用的模块规范一般就是es6模块和commonjs(只用于node)了, node中也已经提供了实验性的es模块支持.
浏览器对es的import
和export
的支持也已经很不错了(除了IE其他主流浏览器都支持了)
好消息是微软将在2022-6-15停止对IE11在win10非长期支持版上的支持