什么是 JavaScript 模塊桨武?
JavaScript 模塊允許我們把項(xiàng)目中的代碼分散成一個(gè)個(gè)單獨(dú)的文件,或者使用通過 npm 安裝的開源模塊具被。用模塊化的方式寫代碼有助于(項(xiàng)目的)組織玻募、維護(hù)、測(cè)試一姿,以及最重要的依賴管理。
當(dāng)我們編寫 JavaScript 時(shí)跃惫,理想情況是保障每個(gè)模塊都專注一件事并把這件事做好叮叹。這種分工可以讓我們?cè)谛枰硞€(gè)模塊時(shí)再去做相應(yīng)的加載。模塊化是是 npm 背后的核心原則爆存。當(dāng)需要某個(gè)特定的功能時(shí)蛉顽,我們能安裝相應(yīng)的模塊并加載到應(yīng)用當(dāng)中。## 什么是 JavaScript 模塊先较?
JavaScript 模塊允許我們把項(xiàng)目中的代碼分散成一個(gè)個(gè)單獨(dú)的文件携冤,或者使用通過 [npm](https://www.npmjs.com/)
安裝的開源模塊。用模塊化的方式寫代碼有助于(項(xiàng)目的)組織闲勺、維護(hù)曾棕、測(cè)試,以及最重要的依賴管理菜循。
當(dāng)我們編寫 JavaScript 時(shí)翘地,理想情況是保障每個(gè)模塊都專注一件事并把這件事做好。這種分工可以讓我們?cè)谛枰硞€(gè)模塊時(shí)再去做相應(yīng)的加載癌幕。模塊化是是 npm
背后的核心原則衙耕。當(dāng)需要某個(gè)特定的功能時(shí),我們能安裝相應(yīng)的模塊并加載到應(yīng)用當(dāng)中勺远。
ES6+npm:
CommonJS
CommonJS規(guī)范是誕生比較早的橙喘。NodeJS就采用了CommonJS。是這樣加載模塊:
var clock = require('clock');
clock.start();
這種寫法適合服務(wù)端胶逢,因?yàn)樵诜?wù)器讀取模塊都是在本地磁盤厅瞎,加載速度很快。但是如果在客戶端宪塔,加載模塊的時(shí)候有可能出現(xiàn)“假死”狀況磁奖。比如上面的例子中clock的調(diào)用必須等待clock.js請(qǐng)求成功,加載完畢某筐。那么比搭,能不能異步加載模塊呢?
AMD
AMD,即 (Asynchronous Module Definition)身诺,這種規(guī)范是異步的加載模塊蜜托,requireJs應(yīng)用了這一規(guī)范。先定義所有依賴霉赡,然后在加載完成后的回調(diào)函數(shù)中執(zhí)行:
require([module], callback);
用AMD寫上一個(gè)模塊:
require(['clock'],function(clock){
clock.start();
});
AMD雖然實(shí)現(xiàn)了異步加載橄务,但是開始就把所有依賴寫出來(lái)是不符合書寫的邏輯順序的,能不能像commonJS那樣用的時(shí)候再require穴亏,而且還支持異步加載后再執(zhí)行呢蜂挪?
CMD
CMD (Common Module Definition), 是seajs推崇的規(guī)范,CMD則是依賴就近嗓化,用的時(shí)候再require棠涮。它寫起來(lái)是這樣的:
define(function(require, exports, module) {
var clock = require('clock');
clock.start();
});
AMD和CMD最大的區(qū)別是對(duì)依賴模塊的執(zhí)行時(shí)機(jī)處理不同,而不是加載的時(shí)機(jī)或者方式不同刺覆,二者皆為異步加載模塊严肪。
AMD依賴前置,js可以方便知道依賴模塊是誰(shuí)谦屑,立即加載驳糯;而CMD就近依賴,需要使用把模塊變?yōu)樽址馕鲆槐椴胖酪蕾嚵四切┠K氢橙,這也是很多人詬病CMD的一點(diǎn)酝枢,犧牲性能來(lái)帶來(lái)開發(fā)的便利性,實(shí)際上解析模塊用的時(shí)間短到可以忽略充蓝。
requireJS和SeaJS的不同
不同之處
兩者的主要區(qū)別如下:
定位有差異隧枫。RequireJS 想成為瀏覽器端的模塊加載器,同時(shí)也想成為 Rhino / Node 等環(huán)境的模塊加載器谓苟。Sea.js 則專注于 Web 瀏覽器端官脓,同時(shí)通過 Node 擴(kuò)展的方式可以很方便跑在 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 在嘗試讓第三方類庫(kù)修改自身來(lái)支持 RequireJS桶良,目前只有少數(shù)社區(qū)采納。Sea.js 不強(qiáng)推沮翔,采用自主封裝的方式來(lái)“海納百川”陨帆,目前已有較成熟的封裝策略。
對(duì)開發(fā)調(diào)試的支持有差異。Sea.js 非常關(guān)注代碼的開發(fā)調(diào)試疲牵,有 nocache承二、debug 等用于調(diào)試的插件。RequireJS 無(wú)這方面的明顯支持纲爸。
插件機(jī)制不同亥鸠。RequireJS 采取的是在源碼中預(yù)留接口的形式,插件類型比較單一识啦。Sea.js 采取的是通用事件機(jī)制负蚊,插件類型更豐富。
還有不少差異颓哮,涉及具體使用方式和源碼實(shí)現(xiàn)盖桥,歡迎有興趣者研究并發(fā)表看法。
總之题翻,如果說(shuō) RequireJS 是 Prototype 類庫(kù)的話,則 Sea.js 致力于成為 jQuery 類庫(kù)腰鬼。