在開發大型的web
項目中,可能會使用到管理js
的模塊化工具。但是在前端輪子漫天飛的時代。那一款js
模塊化工具真正適合我們應用到開發呢?目前比較流行的模塊化工具有RequireJS
、SeaJS
等等。而且模塊化開發工具都有不同的規範去約束例如:AMD CMD CommonJS
。
CommonJS
說道CommonJS
,學習過Node
的同學會比較熟悉,CommonJS
是服務器模塊的規範,Node
採用了這個規範。如果我們也想在瀏覽器中使用到CommonJS
的規範的話,可以使用browserify
。
下面用browserify
做一個示例。首先需要安裝Node
和npm
(假設你已經安裝好了):
npm install browserify -g
接着使用npm
安裝browserify
,記得要安裝到全局環境中。然後新建兩個js
文件,分別是a.js
和b.js
。
// a.js
module.exports = function () {
console.log('This is a.js');
};
//b.js
var a = require('./a');
a();
console.log('This is b.js');
我們編寫好代碼之後,在命令行中運行:
browserify b.js -o bundle.js
node bundle.js // 運行 bundle.js
This is a.js // 輸出
This is b.js // 輸出
然後我們就發現了目錄下多了一個bundle.js
的文件。這就是browserify
根據我們寫的代碼最後編譯出來的。上面只是用了browserify
拋磚引玉的介紹了一下如何在客戶端中CommonJS
規範。
- 爲什麼要使用
CommonJS
規範呢?
如果經常寫Node
的同學可能會對CommonJS
規範比較瞭解一些,上手比較容易。
外鏈
AMD
說道模塊化的話,大多數的同學都應該瞭解RequireJS
,而且RequireJS
是基於AMD
規範的。下面也用一下小栗子來體驗一下RequireJS
。新建兩個文件一個是a.js
另一個是index.html
。
a.js
:
define(function () {
console.log('hello RequireJS!');
});
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script data-main="a.js" src="http://apps.bdimg.com/libs/require.js/2.1.9/require.min.js"></script>
</body>
</html>
接着用瀏覽器打開index.html
,發現控制檯輸出了hello
RequireJS!
。就表示已經成功了。上面只是一個非常簡單的栗子。體驗了一下RequireJS
。
- 爲什麼要使用
AMD
規範呢?
因爲AMD
是專門爲瀏覽器中js
環境設計的規範。它吸取了CommonJS
的一些優點,但是沒有全部都照搬過來。也是非常容易上手。
外鏈
CMD
說道AMD
的話,又會想起有個叫CMD
的東西。而且SeaJS
是推薦是用CMD
的寫法,那麼就使用SeaJS
來編寫一個簡單的栗子:
也是新建兩個文件,greet.js
和index.html
:
greet.js
:
define(function (require, exports) {
function helloPython() {
document.write("Hello,Python");
}
function helloJavaScript() {
document.write("Hello,JavaScript");
}
exports.helloPython = helloPython;
exports.helloJavaScript = helloJavaScript;
});
index.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<script src="http://apps.bdimg.com/libs/seajs/2.3.0/sea.js"></script>
<script>
seajs.use(['./greet'], function (Greet) {
Greet.helloJavaScript()
});
</script>
</body>
</html>
看到頁面上輸出了Hello,JavaScript
,就表示成功了。看了前面AMD
和這個CMD
的栗子之後,大部分人會感覺兩者寫起來好像沒什麼區別。雖然寫起來像,還是有一些區別:
- 對於依賴的模塊,
AMD
是提前執行,CMD
是延遲執行。不過RequireJS
從2.0
開始,也改成可以延遲執行(根據寫法不同,處理方式不同)。CMD
推崇as lazy as possible
。 CMD
推崇依賴就近,AMD
推崇依賴前置。AMD
的API
默認是一個當多個用,CMD
的API
嚴格區分,推崇職責單一。比如AMD
裏,require
分全局require
和局部require
,都叫require
。CMD
裏,沒有全局require
,而是根據模塊系統的完備性,提供seajs.use
來實現模塊系統的加載啓動。CMD
裏,每個API
都簡單純粹。
以上區別都是摘抄自:AMD 和 CMD 的區別有哪些?玉伯的回答。
外鏈
ES6 Module
上面解決js
模塊化的方法都是使用第三方的庫來解決的。但是欣慰的是,ES6
幫我們解決了原生js
能夠不依賴第三方的庫來使用模塊解決方案。
歷史上,JavaScript一直沒有模塊(module)體系,無法將一個大程序拆分成互相依賴的小文件,再用簡單的方法拼裝起來。其他語言都有這項功能,比如Ruby的require、Python的import,甚至就連CSS都有@import,但是JavaScript任何這方面的支持都沒有,這對開發大型的、複雜的項目形成了巨大障礙。《ECMAScript 6 入門》 - 阮一峯
還是寫一個小栗子瞭解一下,又是新建兩個文件a.js
和b.js
:
// a.js
var num1 = 1;
var num2 = 2;
export {num1, num2};
// b.js
import {num1, num2} from './a.js';
function add(num1, num2) {
return num1 + num2;
}
console.log(add(num1, num2));
因爲使用到了ES6
的語法,所以需要轉碼器來把代碼轉換成ES5
的代碼。只需要使用npm
安裝traceur
就行了。
npm install traceur -g
安裝好之後,我們就通過traceur
命令來運行b.js
。就和Node
運行js
文件一樣。
traceur b.js
3 // 輸出
如果命令行中輸出了3,就表示成功了。
- 爲什麼要使用
ES6 Module
規範呢?
不用依賴第三方的庫來結局模塊化的問題,語法簡單簡潔。上手簡單。可能是未來模塊化解決方案的首選。