什么是 JavaScript 模塊?
JavaScript 模塊允許我們把項目中的代碼分散成一個個單獨的文件,或者使用通過 npm 安裝的開源模塊。用模塊化的方式寫代碼有助于(項目的)組織、維護、測試,以及最重要的依賴管理。
當我們編寫 JavaScript 時,理想情況是保障每個模塊都專注一件事并把這件事做好。這種分工可以讓我們在需要某個模塊時再去做相應(yīng)的加載。模塊化是是 npm 背后的核心原則。當需要某個特定的功能時,我們能安裝相應(yīng)的模塊并加載到應(yīng)用當中。## 什么是 JavaScript 模塊?
JavaScript 模塊允許我們把項目中的代碼分散成一個個單獨的文件,或者使用通過 [npm](https://www.npmjs.com/) 安裝的開源模塊。用模塊化的方式寫代碼有助于(項目的)組織、維護、測試,以及最重要的依賴管理。
當我們編寫 JavaScript 時,理想情況是保障每個模塊都專注一件事并把這件事做好。這種分工可以讓我們在需要某個模塊時再去做相應(yīng)的加載。模塊化是是 npm 背后的核心原則。當需要某個特定的功能時,我們能安裝相應(yīng)的模塊并加載到應(yīng)用當中。
ES6+npm:
CommonJS
CommonJS規(guī)范是誕生比較早的。NodeJS就采用了CommonJS。是這樣加載模塊:
var clock = require('clock');
clock.start();
這種寫法適合服務(wù)端,因為在服務(wù)器讀取模塊都是在本地磁盤,加載速度很快。但是如果在客戶端,加載模塊的時候有可能出現(xiàn)“假死”狀況。比如上面的例子中clock的調(diào)用必須等待clock.js請求成功,加載完畢。那么,能不能異步加載模塊呢?
AMD
AMD,即 (Asynchronous Module Definition),這種規(guī)范是異步的加載模塊,requireJs應(yīng)用了這一規(guī)范。先定義所有依賴,然后在加載完成后的回調(diào)函數(shù)中執(zhí)行:
require([module], callback);
用AMD寫上一個模塊:
require(['clock'],function(clock){
clock.start();
});
AMD雖然實現(xiàn)了異步加載,但是開始就把所有依賴寫出來是不符合書寫的邏輯順序的,能不能像commonJS那樣用的時候再require,而且還支持異步加載后再執(zhí)行呢?
CMD
CMD (Common Module Definition), 是seajs推崇的規(guī)范,CMD則是依賴就近,用的時候再require。它寫起來是這樣的:
define(function(require, exports, module) {
var clock = require('clock');
clock.start();
});
AMD和CMD最大的區(qū)別是對依賴模塊的執(zhí)行時機處理不同,而不是加載的時機或者方式不同,二者皆為異步加載模塊。
AMD依賴前置,js可以方便知道依賴模塊是誰,立即加載;而CMD就近依賴,需要使用把模塊變?yōu)樽址馕鲆槐椴胖酪蕾嚵四切┠K,這也是很多人詬病CMD的一點,犧牲性能來帶來開發(fā)的便利性,實際上解析模塊用的時間短到可以忽略。
requireJS和SeaJS的不同
不同之處
兩者的主要區(qū)別如下:
定位有差異。RequireJS 想成為瀏覽器端的模塊加載器,同時也想成為 Rhino / Node 等環(huán)境的模塊加載器。Sea.js 則專注于 Web 瀏覽器端,同時通過 Node 擴展的方式可以很方便跑在 Node 環(huán)境中。
遵循的規(guī)范不同。RequireJS 遵循 AMD(異步模塊定義)規(guī)范,Sea.js 遵循 CMD (通用模塊定義)規(guī)范。規(guī)范的不同,導(dǎo)致了兩者 API 不同。Sea.js 更貼近 CommonJS Modules/1.1 和 Node Modules 規(guī)范。
推廣理念有差異。RequireJS 在嘗試讓第三方類庫修改自身來支持 RequireJS,目前只有少數(shù)社區(qū)采納。Sea.js 不強推,采用自主封裝的方式來“海納百川”,目前已有較成熟的封裝策略。
對開發(fā)調(diào)試的支持有差異。Sea.js 非常關(guān)注代碼的開發(fā)調(diào)試,有 nocache、debug 等用于調(diào)試的插件。RequireJS 無這方面的明顯支持。
插件機制不同。RequireJS 采取的是在源碼中預(yù)留接口的形式,插件類型比較單一。Sea.js 采取的是通用事件機制,插件類型更豐富。
還有不少差異,涉及具體使用方式和源碼實現(xiàn),歡迎有興趣者研究并發(fā)表看法。
總之,如果說 RequireJS 是 Prototype 類庫的話,則 Sea.js 致力于成為 jQuery 類庫。