領先一步
VMware 提供培訓和認證,以加速您的進展。
了解更多將近十年前,Adrian Colyer 寫了一篇 令人印象深刻的部落格文章,對面向切面程式設計 (AOP) 提出了最佳解釋:清晰簡潔的風格、準確的內容、沒有流行語。如果您看過本系列稍早的 兩篇 文章,您可能已經注意到我們在 Sagan 應用程式的 客戶端模組 中的一些架構選擇,包括使用 JavaScript 模組。
在這篇文章中,我想以 Adrian 文章的風格,帶您了解 JavaScript 模組的基礎知識:清晰、簡潔、準確、沒有流行語!
如果您和我一樣有 Java 背景,某些 JavaScript 語言特性可能會讓您覺得有點奇怪
簡單的 Web 應用程式通常看起來像這樣
<html>
<head>
<!-- scripts are loaded **sequentially** -->
<script src="jquery.js"></script>
<script src="widget.js"></script>
<!-- all objects are in the global namespace,
no way to isolate the code completely! -->
<script>
window.$; // this is jquery
</script>
</head>
</html>
開發人員經常嘗試重複使用功能區塊並管理它們之間的依賴關係。這在以前的情況下真的很難實現:您必須以正確的順序宣告腳本,並在沒有任何關於依賴關係的元數據的情況下避免名稱衝突。隨著應用程式不斷成長,這項任務變成一場噩夢:想像一下在沒有套件或依賴管理基礎架構的好處下管理您的 Java 應用程式!
幸運的是,JS 社群非常清楚模組化的需求,並且在過去幾年中,出現了幾種廣泛採用的方法來解決這個問題
AMD (Asynchronous Module Definition) 就是其中之一
// defining a module that depends on "graphmodule",
// injected in the function definition as an argument
define(["graphmodule"],
function (graph) {
// this module exports a "draw" function
return function draw(data) {
return graph.piechart(data);
}
}
);
AMD 格式通常用於瀏覽器應用程式,因為
CommonJS 是另一種編寫格式,通常用於伺服器端的 Node.js 應用程式,但也用於瀏覽器應用程式。
/**
* Our module's dependencies and API
**/
// we fetch the graph module as a dependency
var graph = require('graphmodule');
// we decorate the `exports` variable to export our function
exports.draw = drawFunc;
/**
* API implementation
**/
function drawFunc(data) {
return graph.piechart(data);
}
您可能發現了與 AMD 的一些差異
define
包裹下一個版本的 JavaScript(技術上稱為 ECMAScript 6)將 標準化 JavaScript 模組化,儘管使用的語法與我們在上面看到的 AMD 或 commonJS 格式略有不同。此外,EcmaScript 6 將解決該領域的許多問題,但也將提供語法糖來定義類似 OO 的類別。
無論您在哪裡使用 JavaScript,無論是客戶端還是伺服器端,都請考慮採用模組化方法——原因與我們在 Java 中這樣做的所有原因相同。精通 JS 模組技術需要一個小的學習曲線,但結果非常值得。
如果您是 JavaScript 模組化的新手,我建議查看 「編寫 CommonJS 模組」教程 以及我們在 Sagan 中使用的模組載入器:curl。一旦您感到熟悉,請查看我們在 Sagan 應用程式中的模組定義。