JS模組化開發規範
JS模組化開發規範,以下介紹三種
commonJS規範(Nodejs模組系統遵循此規範,適用於服務端)
1、 規範定義
CommonJS規範規定,一個檔案就是一個模組,用module變數代表當前模組。 Node在其內部提供一個Module的構建函式。所有模組都是Module的例項
2、 module.exports屬性定義模組
module.exports屬性表示當前模組對外輸出的介面,其他檔案載入該模組,實際上就是讀取module.exports變數。
//moduleA.js
module.exports.funcA= function(){
console.log('This is moduleA!');
}
3、模組引用
require函式的基本功能是,讀入並執行一個JavaScript檔案,然後返回該模組的exports物件。在moduleB模組中載入引入moduleA模組,便可以使用funA方法了,示例程式碼如下:
//moduleB.js
var a = require('./moduleA');
a.funcA();//列印'This is moduleA!'
AMD規範(RequireJs JS模組載入器遵循此規範,適用於瀏覽器)
1、定義模組:define方法 define(id?, [deps,]?, factory);
l 第一個引數,id(名字),是個字串。它指的是定義中模組的名字,這個引數是可選的。如果沒有提供該引數,模組的名字應該預設為模組載入器請求的指定指令碼的名字。如果提供了該引數,模組名必須是“頂級”的和絕對的(不允許相對名字)。
l 第二個引數,dependencies(依賴),是個定義中模組所依賴模組的陣列。依賴模組必須根據模組的工廠方法優先順序執行,並且執行的結果應該按照依賴陣列中的位置順序以引數的形式傳入(定義中模組的)工廠方法中。
l 第三個引數,factory(工廠方法),為模組初始化要執行的函式或物件。如果為函式,它應該只被執行一次。如果是物件,此物件應該為模組的輸出值。
2、require方法:載入模組require([module], callback);
第一個引數[module],是一個數組,裡面的成員就是要載入的模組;第二個引數callback,則是載入成功之後的回撥函式。如果將前面的程式碼改寫成
require(['a'], function (a) {
a.FuncA();
});
//js/index.js(requirejs的使用)
<script data-main="js/ctr/index" src="js/lib/require.js" type="text/javascript"></script>
require.config({
//baseUrl——用於載入模組的根路徑。
//paths——用於對映不存在根路徑下面的模組路徑。
//shims——配置在指令碼/模組外面並沒有使用RequireJS的函式依賴並且初始化函式。
//deps——載入依賴關係陣列
baseUrl : "js",
paths: {
'jquery': '../lib/jquery'
},
shim: {//載入非AMD規範的模組
"underscore" : {
exports : "_";
},
"jquery.form" : {
deps : ["jquery"],//deps陣列,表明該模組的依賴性
exports: 'jqueryForm'
}
}
});
require(['jquery'], function($) {
$(document).on('click', '#clickBtn', function() {
$('#showMsg').html('看看jquery載入進來了沒有');
});
});
CMD規範(seaJS 模組載入器)
1、規範定義
CMD是國內大牛玉伯在開發SeaJS的時候提出來的,屬於CommonJS的一種規範,根據瀏覽器的非同步環境做了自己的實現。它和 AMD 很相似,儘量保持簡單,並與 CommonJS 和 Node.js 的 Modules 規範保持了很大的相容性。
2、define方法:定義模組 define( id?, [deps,]?, factory ); 前兩個引數項可選
define('hello', ['jquery'], function(require, exports, module) {
// 模組程式碼
});
3、require方法:載入模組
1.require 是同步往下執行,require.async 則是非同步回撥執行。require.async 一般用來載入可延遲非同步載入的模組。
2.除了給 exports 物件增加成員,還可以使用 return 直接向外提供介面
3.module.exports 的賦值需要同步執行,不能放在回撥函式裡。
4.exports 是 module.exports 的一個引用
define(function(require, exports, module) {
// 錯誤用法,對 module.exports 的賦值需要同步執行,不能放在回撥函式裡。
setTimeout(function() {
module.exports = { a: "hello" };
}, 0);
// 非同步載入模組,在載入完成時,執行回撥
require.async(['./c', './d'], function(c, d) {
c.doSomething();
d.doSomething();
});
//向外暴露介面的方法3種
// 1.給 module.exports 賦值
module.exports = new SomeClass();
// 2.給 exports 物件增加成員
exports.doSomething = function() {};
// 3.通過 return 直接提供介面
return {
foo: 'bar',
doSomething: function() {}
};
});
//js/index.js(seajs的使用)
define(function(require, exports, module) {
// var $ = require("$");
module.exports= {
init: function() {
console.log('index.js is loaded!');
}
};
});
seajs.config({
base: "./js/lib/",// Sea.js 的基礎路徑
alias: {// 別名配置
'$':'jquery/1.12.3/jquery-1.12.3',
'jquery':'jquery/1.12.3/jquery-1.12.3',
},
paths: {// 路徑配置
'basePath': './js/lib/'
},
vars: {// 變數配置
'jquery_version': 'jquery-1.12.3'
},
map: [// 對映配置
[ '.js', '-debug.js' ]
],
preload: ['$'], //預載入項'$'
debug: true,// 除錯模式
charset: 'utf-8'// 檔案編碼
});
seajs.use(['$','./js/ctr/index.js'], function($,index) {$(document).ready(function(){index.init();});
});