在我們最初寫代碼的時候,引入JS
文件用script
標籤來引入,並且在引入多個JS
文件時,當前文件所依賴的JS
文件必須放在前面。也就存在一個順序的問題,而且這是由開發者去判斷和把控的。而現在前端項目越來越複雜,難免會出現很多很多script
標籤引入JS
,這無論對於開發和維護都有着一定的缺點。所以出現了模塊化的概念。
模塊化的形式有很多中,比如把某個特定功能封裝成一個函數,但是存在着一個問題,很有可能會出現命名衝突等問題。針對這種問題,又有了對象的方式來模塊化,這種不會出現命名衝突,但是外界卻可以改變對象內的成員。又有了下面這種方式:
var obj = (function(){
var name = 'liu';
var job = 'Web developer';
function sayName() {
console.log(name + ' is a ' + job);
}
return {
sayName: sayName
}
})()
這樣外界就不會修改沒有暴露出來的對象內的變量。
上面這些是前端模塊化的基礎。目前通用的模塊化規範主要有COMMONJS
、AMD
、CMD
等等。
COMMONJS
COMMONJS
主要是用於服務端的模塊化規範,可以說NodeJS
是它的最佳實踐。看下面一個例子:
//導入一個文件系統模塊,返回的是一個對象;
var fs = require('fs');
//調用對象的readFile方法,讀文件。
fs.readFile('test.txt', function(data){
console.log(data);
});
上面是一個讀文件的操作,主要引入文件系統模塊,這個是一個同步的過程。
當然,也可以自定義一個模塊實現特定的功能。比如要實現一個Multi模塊,可以這樣來實現:
//multi.js
function multi(a ,b) {
return a*b;
}
module.exports = {
multi: multi
}
//moduleTest.js
var obj = require('./multi.js');
var res = obj.multi(3, 4);
console.log(res);
結果如下:
AMD
上面的COMMONJS
規範不適合瀏覽器端的模塊化開發,因爲COMMONJS
去請求模塊是一個同步的過程,如果瀏覽器用這種規範去開發很可能會出現阻塞情況/假死情況。因此AMD
規範就是爲解決這種情況而出現的。
由於不是原生JS
所支持的,所以AMD
規範需要用到RequireJS
庫。
AMD的用法如下:
定義模塊: define([依賴的模塊], function(){ //自定義模塊 });
引入模塊:require([依賴的模塊], function(){ //回調 })
在這裏,需要說明的一點是:RequireJS
是依賴前置,先去執行依賴的模塊,然後再執行當前模塊。
CMD
CMD
典型的就是SeaJS
。SeaJS
與RequireJS
實現上是差不多的,但是還是有一些區別,主要是在定義方式上和模塊的執行時機上。
定義模塊: define(function( require, exports, module ){ })
可以看到,SeaJS
在定義模塊的時候,並不會像RequireJS
那樣依賴前置,而是就近依賴的原則,需要的時候再去require
。SeaJS
主要是對模塊先加載不執行,等到遇到require
的時候纔會去執行模塊。
對於RequireJS
和SeaJS
的差異可以看下面這個例子:
//c.js
define(function(require, exports, module){
console.log('c Module');
require('./b.js');
console.log('c module finished');
})
//b.js
define(function(require, exports, module){
console.log('b Module');
require('./a.js');
console.log('b module finished');
})
//a.js
define(function(require, exports, module){
console.log('a Module');
})
//html文件
//requirejs文件部分代碼
<script src="require.min.js" data-main="c.js"></script>
//SeaJs文件部分代碼
<script src="Sea.js"></script>
<script>seajs.use('./c'); </script>
大家可以猜猜兩種執行結果有什麼不同,這裏就不做驗證了。
上面這些就是JS模塊化的通用方法總結,當然,ES6中已經有了Module模塊化的概念,後面還會再對這個進行整理。