commonjs,AMD,CMD,ES6模块化总结
2019-04-23 本文已影响0人
李牧敲代码
之前用webpack开发前端项目的时候,发现什么模块化的import
,export
, module,exports都随便用,但是一旦离开了webpack就发现这也用不了,那也会报错,很是扎心。遂,这里对commonjs,AMD,CMD,ES6模块化做一个总结,好好梳理一下。
【commonJS】
目的:模块化前端技术栈,偏server端,是一种规范
特点:
- 一个文件就是一个模块,拥有单独的作用域;
- 普通方式定义的变量、函数、对象都属于该模块内;
- 通过require来加载模块;
- 通过exports和modul.exports来暴露模块中的内容;
- 同步加载模块,当所有模块加载完毕才执行下一步(不适合浏览器端,因为node的性能较好取决于磁盘,而前端浏览器还受制于网络)。
实践: Node,webpack
例子:
目录结构:

//main.js
const a = require('./a');
console.log(a);
//a.js
let a = 1;
module.exports = a;//exports === module.exports
测试:

AMD(Asynchronous Module Definition)
目的:模块化前端技术栈,偏浏览器端
特点:依赖前置,异步加载模块,只有一个API,是一种规范
语法:define(<模块名称>, [依赖数组], 回调函数)
实践: requireJS,webpack
例子:
目录结构:

<!--index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
success
<script data-main="./main.js" src="https://cdn.bootcss.com/require.js/2.3.6/require.min.js"></script>
</body>
</html>
//main.js
require.config({
"jquery": {
path: 'https://cdn.bootcss.com/require.js/2.3.5/require.min.js'
},
"a": {
path: './a.js'
}
})
define('main', ['jquery', 'a'], function(jQuery, a) {
console.log(jQuery);
console.log(a)
})
//a.js
define('a', [], function() {
return {
msg: 'i am a!'
}
})
测试:

CMD(Common Module Definitio)
模块化前端技术栈,偏l浏览器端。
特点,依赖不前置,哪里用到模块哪里开始加载模块。
实践: seajs
例子:
目录结构:

//jquery.js
define(function (require, exports, module) {
jquery源码
}
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.bootcss.com/seajs/3.0.3/sea.js"></script>
<script src="./sea.js"></script>
</head>
<body>
</body>
</html>
//main.js
define(function(require, exports, modules) {
var $ = require('jquery');
var changeText = require('./a.js')
console.log(changeText.text)
console.log('$', $)
})
//sea.js
seajs.config({
alias: {
'jquery': './jquery.js'
}
})
console.log(seajs)
seajs.use('./main.js')
//a.js
define(function (require, exports, module) {
var textContent = 'yes it works';
exports.text = textContent;
//or
//module.exports = {
//text: textContent
//}
})
测试:

ps:
Node实现了CommonJS规范,并不代表实现了ES6的所有语法,同样的,webpack实现了CommonJS和AMD规范不代表实现了ES6的所有语法,还需要babel-loader支持。ES6中导入模块和导出模块分别是通过import
和module.exports
来处理的。
比如下面的例子中左右两边是等效的。
import a from './a' 等于 const a = require('./a')
AMD , CMD, ES6模块化区别
AMD:
优点:
- 通过setTimeout使得异步模块不会阻塞浏览器渲染,提高性能。
- 对异步模块支持较好(尤其是CDN)
缺点:
- 依赖前置,对于那些“条件依赖”就会显得浪费。
CMD
优点:
- 通过添加
<script src='' async>
防止阻塞浏览器渲染,监听script标签的onloade事件处理回调、提高性能。 - 依赖就近,用到的时候再加载(会做缓存),防止浪费。
缺点:
- 对于没有CMD话的模块就比较麻烦了,只能下载下来在本地CMD化。
ES6
对于ES6的模块化我目前能想到的优点就是:
写法比较灵活外就是不需要额外的代码,原生支持。而且拿到值是值的引用,保证是模块最新的值
参考文献
commonjs规范
https://blog.csdn.net/w390058785/article/details/83380185
https://www.cnblogs.com/ooooevan/p/5897586.html
https://www.cnblogs.com/wbxjiayou/p/6197678.html
https://blog.csdn.net/qq_15096707/article/details/52493512
https://blog.csdn.net/tangxiujiang/article/details/81104174
https://blog.csdn.net/arsaycode/article/details/78959780
seajs简单使用