为什么要进行模块化开发?
1.当你写了一个这样的comm.js文件时,里面有function tab(){}方法,这时,你给你的同事用,你同事把这个comm.js引入页面后,在页面上又写了一个function tab(){},这时,就会覆盖你在comm.js中的tab方法。因为这个同事不知道你comm.js中有tab这个方法名。
2.如果你同事在页面上引入了你写的comm.js后,又引入了一个第三方插件xxx,而这个xxx插件里面刚好也有tab方法,那这时就会出现问题。你同事就会找你,说你写的comm.js有问题。
这时,你可能会这样写comm.js。
var chaojidan = {};
chaojidan.tab = function(){};
这种命名空间的方式,可以降低冲突,但是无法避免冲突。
3.假如你的comm.js中现在有20个方法,但是我们的页面现在只需要tab这个功能,也就是只需要调用tab方法。那么,这时,你可能会把comm.js分成多个js文件,比如:tab.js,comm.js,drag.js。这时,你的页面就会出现引入多个js的情况,比如:
<script src="a.js"></script>
<script src="b.js"></script>
<script src="c.js"></script>
<script src="d.js"></script>
但是,如果这时a.js依赖于d.js的话,就会出现问题。
4.上面的依赖问题,有人说,可以把d.js放在a.js上面不就行了。但是这不能解决依赖问题,比如:当你这样写好一个页面后,产品经理要你添加功能,这时你又添加了一个e.js,而e.js依赖于a.js。这时,你在新页面添加新功能时,你必须把d.js,a.js,e.js按顺序进行加载。当出现大规模的依赖时,你就会奔溃了。
模块化的库,sea.js(CMD),require.js(AMD)。
我们来看看sea.js如何解决js模块化开发:
1.引入sea.js库。
2.如何变成模块,通过define方法。比如:
define(function(require,exports,module){
function tab(){
....
}
exports.tab= tab;
})
这时,你在这里定义一个function tab(){},不会跟define里面的那个tab方法起冲突。
3.如何调用模块?通过seajs.use()方法,比如:
seajs.use("./comm.js",function(ex){
ex.tab();
})
4.如何解决模块间的依赖问题,通过require方法。比如:
a.js
define(function(require,exports,module){
var d = require("./d.js"); //模块a依赖模块d。
function tab(){
d.drag();
}
exports.tab= tab;
})
d.js
define(function(require,exports,module){
function drag(){
....
}
exports.drag= drag;
})
上面的require方法加载模块是同步的,而require.async()方法,加载模块是异步的。
他们之间的区别是什么呢?举个例子:
a.js
define(function(require,exports,module){
var d = require("./d.js"); //模块a依赖模块d。
var ele = document.getElementById("input"); //当你在页面上调用seajs.use("./a.js")时,页面上的input元素就绑定了click事件。但是这时d.js,b.js,以及a.js都从服务器下载到浏览器端了。尽管这时还不需要b.js模块,只有点击了input元素才需要。这时,我们只需要把require("./b.js").scale(); 改成require.async("./b.js",function(ex){ex.scale()});这时,只会下载d.js和a.js,而b.js不会下载,只有等你click元素input时,才会去下载b.js,然后执行b.js,执行结束后,就会调用回调函数,这时,就调用ex.scale()方法了。这叫做按需载入。
ele.onclick = function(){
require("./b.js").scale();
}
})
b.js
define(function(require,exports,module){
function scale(){
....
}
exports.scale= scale;
})
js模块化的发展:
node.js是最早使用模块化进行开发的,遵循的规范是:CommonJS,这是服务端的模块化规范,服务器使用此规范进行开发,是因为它所需要的文件就在服务器本地。而浏览器端需要的文件在服务器端,不在浏览器本地,因此就出现了AMD规范。
require.js遵守AMD规范,在浏览器端进行模块化开发的库。
sea.js遵守CMD规范,在浏览器端进行模块化开发的库。
我们开发网页一般要遵守这种开发模式就行了:
1.底层库jQuery
2.组件开发,可以基于jQuery
3.业务应用开发,基于jQuery和组件
通过sea.js等模块化库,把上面所有的模块连起来。
模块化在前端开发中还是很重要的,ECMAScript第六版将正式支持模块化语法,也就是说不用利用模块化库,就能实现模块化的功能。
加油!