前言
模块化赋给了我们什么能力呢? 以及有哪些模块化规范?
1、代码复用;2、命名冲突;3、文件依赖;
一、commonJS
1、如何加载
1、模块可多次加载但是只会在第一次加载时运行,后续加载读取缓存;
2、会阻塞后面代码运行 【同步执行】;
2、场景
nodejs模块化规程参照commonJS实现的;
3、使用
// b.js
exports.b = 'bbbbb'; // 等价 module.exports.b = 'bbbbb' exports只是对module.exports的一个引用
// a.js
const b = require('./b.js');
console.log(b); // bbbbb
二、AMD
1、如何加载
1、异步加载,防止浏览加载多模块卡顿;
2、管理模块之间的依赖性,便于代码的编写和维护;
2、场景
浏览器环境,requireJS是参照AMD规范实现的;
3、使用
// 语法
// define([id], [dependencies], factory)
// mod1.js
define('mod1',[],function(){
// ...
return {
// ...
}
})
// mod2.js
define('mod2', ['mod1'], function (mod1) {
// ...
return {
// ...
}
})
// 加载
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="require.js"></script>
<script type="text/javascript" src="mod1.js"></script>
<script type="text/javascript" src="mod2.js"></script>
<script type="text/javascript">
require(['mod1','mod2'],function(mod1, mod2){
// ...
});
</script>
</body>
</html>
三、
CMD
1、AMD CMD区别
CMD(Common Module Definition),通用模块定义,它解决的问题和AMD规范是一样的,只不过在模块定义方式和模块加载时机上不同,CMD也需要额外的引入第三方的库文件,SeaJS
-
AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块
-
CMD推崇就近依赖,只有在用到某个模块的时候再去require
2、场景
浏览器或服务器环境
3、使用
// CMD
define(function(require,exports,module){
var a=require('./a')
a.doSomethimg()
var b=require('./b')
b.doSomething()
})
// AMD
define(['./a','./b'],function(a,b){
a.doSomething()
b.dosomething()
})
四、ESM(ES6 Module)
1、如何加载
1、按需加载(编译时加载)
2、import和export命令只能在模块的顶层,不能在代码块之中(如:if语句中),import()语句可以在代码块中实现异步动态按需动态加载
2、场景
浏览器或服务器环境(@std/esm)
3、使用
/*错误的写法*/
// 写法一
export 1;
// 写法二
var m = 1;
export m;
// 写法三
if (x === 2) {
import MyModual from './myModual';
}
/*正确的三种写法*/
// 写法一
export var m = 1;
// 写法二
var m = 1;
export {m};
// 写法三
var n = 1;
export {n as m};
// 写法四
var n = 1;
export default n;
// 写法五
if (true) {
import('./myModule.js')
.then(({export1, export2}) => {
// ...·
});
}
// 写法六
Promise.all([
import('./module1.js'),
import('./module2.js'),
import('./module3.js'),
])
.then(([module1, module2, module3]) => {
···
});