CommonJS(CJS)--同步加载
特点:
-
封闭的独立作用域,暴露出去的是拷贝值,不会影响内部值;
-
使用require导入模块
-
使用
module.exports或者exports[xxx]导出内容
优点:
率先在服务端实现了从框架层面解决依赖模块化、全局变量污染的问题
缺点:
是针对服务端的解决方案,对异步场景没有过多的处理和考虑;
- CSJ是同步加载,对于Nodejs服务端加载时,由于本地资源不需要网络请求,同步加载在性能方面比较优势;
- 浏览器环境通常需要网络请求来获取资源,如果同步加载的话,一旦网络环境不好,或者某个模块加载较慢,影响较大;
使用方式:
- ①给
module.exports赋值, 重复赋值,导出的对象会被覆盖
//exports.js
module.exports={
a:1
}
module.exports={
c:3
}
//script.js
var obj = require('./exprot');
console.log('log=>obj',obj);//log=>obj { c: 3 }
- ②给
exports添加属性和赋值,操作的都是exports对象
//exports.js
exports.b = 2;
exports.d = 4;
//script.js
var obj = require('./exprot');
console.log('log=>obj',obj);//log=>obj { b: 2, d: 4 }
- ③同时使用
module.exports和exports(不建议)- 给
module.exports赋值会覆盖导出的内容 exports类似module.exports的快捷方式,默认指向module.exportsmodule.exports原始值一般是一个空对象
- 给
//exports.js
module.exports={
a:1
}
exports.b = 2;
module.exports={
c:3
}
exports.d = 4;
//script.js
var obj = require('./exprot');
console.log('log=>obj',obj);//log=>obj { c: 3 }
AMD规范(异步模块定义)
特点
- 需要引入require.js资源
- 异步加载
- 允许定制回调函数
- 核心api是
define函数
优点:
- 相比CJS来说,AMD支持了异步模块加载,解决了浏览器异步加载模块的问题
- 对于NodeJs这样的服务器端,AMD的模块载入无需阻塞服务器进程,同样提高了性能
缺点:
- 由于依赖前置,没有按需加载,不论用或者不用,都提前加载执行,影响性能
使用方式:
资源目录:
-amd.html
-Require.js
-module -丨
丨-moduleA.js
丨-moduleB.js
amd.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<script src="Require.js"></script>
<script>
require(['module/moduleA', 'module/moduleB'],
function(moduleA, moduleB) {
console.log('moduleA.getMessage():',moduleA.getMessage());//moduleA.getMessage(): 这是module A的msg
console.log('moduleB.getMessage:',moduleB.printMessage);//moduleB.getMessage: ƒ () {//...} moduleB暴露的printMessage函数
moduleB.printMessage() // 这是module A的msg 执行的是模块B中,加载的模块A的printMessage函数
}
);
</script>
<body>
</body>
</html>
module/moduleA.js
define(function() {
var message = "这是module A的msg";
return {
getMessage: function() {
return message;
}
}
});
module/moduleB.js
define(['module/moduleA'], function(moduleA) {
return {
printMessage: function() {
console.log(moduleA.getMessage());
}
}
});
UMD规范(CJS + AMD)
特点
- 由于 CJS 与 AMD 方式同时存在,导致有的 模块是 CJS 有的是 AMD 方式,对于三方引用时很不友好,于是就有了UMD
- UMD = CJS + AMD;(使用
IIFE[立即执行函数]实现的一种兼容规范)
优点:
- 跟AMD一样,实现了异步加载
缺点
- 融合了CJS和AMD,一样是依赖前置,不论用或者不用,都提前加载
实现方式:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery', 'underscore'], factory);
} else if (typeof exports === 'object') {
// Node, CommonJS-like
module.exports = factory(require('jquery'), require('underscore'));
} else {
// Browser globals (root is window)
root.returnExports = factory(root.jQuery, root._);
}
}(this, function ($, _) {
// methods
function a(){}; // private because it's not returned (see below)
function b(){}; // public because it's returned
function c(){}; // public because it's returned
// exposed public methods
return {
b: b,
c: c
}
}));
CMD规范(通用模块定义)
特点
- Sea.js的模块化规范,它是一种在浏览器端使用的模块加载器,需要引入sea.js资源
- 基于cjs规范
优点:
- 按需加载,就近加载,延迟执行,提升性能
-
在
define的回调函数中的require中按需加载(下面的module.js有demo)
-
缺点:
- 依赖于打包,加载逻辑会打包到模块中,增加了模块体积
使用方式:
资源目录:
-app.js
-cmd.html
-module.js
-sea.js
amd.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sea.js Demo</title>
</head>
<body>
<script src="./sea.js"></script>
<script>
seajs.use('./app.js');//5
seajs.use(['./module.js'],function(add){
console.log('log=>sum',add(1,2)); //3
})
</script>
</body>
</html>
app.js
define(function(require) {
// 导入module.js模块
var add = require('./module');
// 调用add函数
var result = add(2, 3);
// 输出结果
console.log(result); // 5
});
module.js
define(function(require, exports, module) {
// require('./xxx') <---------在这里按需加载
// 定义add函数
function add(a, b) {
return a + b;
}
//这里的导出与cjs是一样的
//exports.min = function(a, b){ return a > b ? b : a; }
// 导出add函数,以便在其他模块中使用
module.exports = add;
});
ESM(es6的导入导出规范)
特点
- ES6 在语言标准的层面上,实现了模块化,旨在成为浏览器和服务器通用的模块化方案,用 export 导出模块,import 导入模块。
import和export语句属于ES模块化语法,需要在支持ES模块的环境中使用,例如在Node.js或者使用工程化工具(如Webpack、Babel等)进行构建。
优点:
- 规范了此前的不同标准。
使用方式:
导出多个声明
//export.js
export test = () => {}
//import.js
import { test } from './export.js'
导出单个内容
//export.js
export default { name:'tom' }
//import.js
import defaultExport from './export.js
混用
//export.js
export test = () => {}
export default { name:'tom' }
//import.js
import defaultExport,{test} from './export.js
//defaultExport只是别名