目下最流行的三种模块引入规则: commonjs, AMD(RequireJs),CMD(SeaJs),其实后两者可以归为一类,为什么呢?因为使用起来很相似,不过细细一看,他们好像都差不多,上代码看看
// commonJs
// a.js
module.exports.a = 1;
module.export.b = 2;
// b.js
const module_a = require("./a.js")
console.log(module_a.a) // 1
console.log(module_a.b) // 2
amd和cmd的话呢,比较久远了,可能大家都没见过,其实我也是之前用过一段时间,那已经是4年前的事情了,所以也都记不得了,这里是重新学习了一遍,并记录下来。
首先要知道common.js创建之初是为了给nodejs使用,所以目标就是服务端,所有的文件都在服务端,所以文件的读取很快,同步的操作并不会造成很大的影响,但是浏览器端还没有好的模块加载方式,这时有人就提出来了RequireJs,这个专门就是为了浏览器端,浏览器端如果想加载模块的话,同步太影响效率,如果同时请求多个模块,一个卡住了,后面全都要卡住,然后页面就白屏,很不友好,所以requirejs就主打异步加载模块,同时也方便了大家对于模块的管理,具体详情大家也可以去看看阮一峰老师的介绍 http://www.ruanyifeng.com/blog/2012/11/require_js.html
下面来展示一个小demo,让大家感受一下requirejs的使用方法
// 目录为下
----
- js
- libs // 放置各种框架
~ require.js
- modules // 放置自己编写的模块
~ alter.js
~ hhh.js
~ main.js // 主js,入口文件
index.html
// 正文开始
// hhh.js
// define的第一个参数可以选择用一个字符串,这个表示当前模块的名字,如果指定了这个名字,那么后续初始化的时候必须使用这个名字,否则会报错
// 如果不写名字,也可以直接定义方法,函数中使用return关键字将需要暴露出来的变量暴露出来
define("hhh", function () {
return {
a: 1,
add: (...args) => args.reduce((prev, curr) => prev + curr),
};
});
// alter.js
// 第一个参数如果是个数组,则说明是引入的其他模块,这个模块的名字是在main.js中定义的名字,
// 第二个参数是一个函数,函数接受与第一个参数长度一致的参数,也就对应着第一个参数数组中的每一个模块,同样通过return来暴露对象
define(["hhh"], function (hhh) {
console.log(hhh);
console.log(hhh.add(1, 2, 3, 4));
const num = hhh.add(1, 2, 3, 4);
return {
num,
};
});
// main.js
// 这个文件是作为整个程序的入口文件,使用匿名函数自执行来避免全局污染
// 首先使用config来对整个程序进行一个配置,主要是paths,来配置模块的名字和模块的地址,
// baseUrl只是为了简写后面path的路径引用
// 注意一点: paths中配置的路径不用加.js,因为require.js会自动帮你加上.js, 如果你加了他也不会智能的帮你省略,所以会导致出现aa.js.js这种情况,也就会导致报错
// 接下来就是引入模块,参数跟alter.js中定义模块的方法类似,只不过define换成了requirejs
(function () {
requirejs.config({
baseUrl: "./js/modules/",
paths: {
hhh: "./hhh",
alter: "./alter",
},
});
requirejs(["alter"], function (alt) {
console.log(alt.num);
});
})();
// index.html
// 这里需要引入require.js以及我们的程序入口文件main.js
// 这里有两种方法,
// 第一种(推荐): <script src="./js/libs/require.js" data-main="./js/main"></script>
// data-main属性的作用是,指定网页程序的主模块,当require.js被加载完毕后,就会立刻去加载./js/main.js文件,.js可写可不写
// 如果第一种理解不了的话,那就用最原始的方法, 也就下面的方法,分两次加载
<!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>
<body>
<!-- <script src="./js/libs/require.js" data-main="./js/main"></script> -->
<script src="./js/libs/require.js"></script>
<script src="./js/main.js"></script>
</body>
</html>
cmd呢,代表性的框架就是sea.js, SeaJS的作者是前淘宝UED,现支付宝前端工程师玉伯。cmd融合了amd和commonJs,所以写法上能看到两者的影子,具体用代码来看看
// hello.js
define(function(require, exports, module) {
var $ = require('jquery');
exports.sayHello = function() {
$('#hello').toggle('slow');
};
});
// main.js
seajs.config({
alias: {
'jquery': 'http://modules.seajs.org/jquery/1.7.2/jquery.js'
}});
seajs.use(['./hello', 'jquery'], function(hello, $) {
$('#beautiful-sea').click(hello.sayHello);
});
// index.html
...
<script src="./js/libs/sea.js"></script>
<script src="./js/main.js"></script>
...
现在大多数都在使用common.js了,es6之后又推出了import来引入模块,导出模块的方式也从module.exports = {}改成了 export default {} 或者单独的export const aa = 1等;
配合上webpack,glup等模块打包器,能够很好的对程序进行扩展以及模块的使用。