JavaScript的RequireJS庫(kù)入門(mén)指南
簡(jiǎn)介
如今最常用的JavaScript庫(kù)之一是RequireJS。最近我參與的每個(gè)項(xiàng)目,都用到了RequireJS,或者是我向它們推薦了增加RequireJS。在這篇文章中,我將描述RequireJS是什么,以及它的一些基礎(chǔ)場(chǎng)景。
異步模塊定義(AMD)
談起RequireJS,你無(wú)法繞過(guò)提及JavaScript模塊是什么,以及AMD是什么。
JavaScript模塊只是遵循SRP(Single Responsibility Principle單一職責(zé)原則)的代碼段,它暴露了一個(gè)公開(kāi)的API。在現(xiàn)今JavaScript開(kāi)發(fā)中,你可以在模塊中封裝許多功能,而且在大多數(shù)項(xiàng)目中,每個(gè)模塊都有其自己的文件。這使得JavaScript開(kāi)發(fā)者日子有點(diǎn)難過(guò),因?yàn)樗鼈冃枰掷m(xù)不斷的關(guān)注模塊之間的依賴性,按照一個(gè)特定的順序加載這些模塊,否則運(yùn)行時(shí)將會(huì)放生錯(cuò)誤。
當(dāng)你要加載JavaScript模塊時(shí),就會(huì)使用script標(biāo)簽。為了加載依賴的模塊,你就要先加載被依賴的,之后再加載依賴的。使用script標(biāo)簽時(shí),你需要按照此特定順序安排它們的加載,而且腳本的加載是同步的??梢允褂胊sync和defer關(guān)鍵字使得加載異步,但可能因此在加載過(guò)程中丟失加載的順序。另一個(gè)選擇是將所有的腳本捆綁打包在一起,但在捆綁的時(shí)候你仍然需要把它們按照正確的順序排序。
AMD就是這樣一種對(duì)模塊的定義,使模塊和它的依賴可以被異步的加載,但又按照正確的順序。

CommonJS, 是對(duì)通用的JavaScript模式的標(biāo)準(zhǔn)化嘗試,它包含有 AMD 定義 ,我建議你在繼續(xù)本文之前先讀一下。在ECMAScript 6這個(gè)下一版本JavaScript 規(guī)范中,有關(guān)于輸出,輸入以及模塊的規(guī)范定義,這些將成為JavaScript語(yǔ)言的一部分,而且這不會(huì)太久。這也是關(guān)于RequireJS我們想說(shuō)的東西。
RequireJS?
RequireJS是一個(gè)Javascript 文件和模塊框架,可以從 http://requirejs.org/下載,如果你使用Visual Studio也可以通過(guò)Nuget獲取。它支持瀏覽器和像node.js之類(lèi)的服務(wù)器環(huán)境。使用RequireJS,你可以順序讀取僅需要相關(guān)依賴模塊。
RequireJS所做的是,在你使用script標(biāo)簽加載你所定義的依賴時(shí),將這些依賴通過(guò)head.appendChild()函數(shù)來(lái)加載他們。當(dāng)依賴加載以后,RequireJS計(jì)算出模塊定義的順序,并按正確的順序進(jìn)行調(diào)用。這意味著你需要做的僅僅是使用一個(gè)“根”來(lái)讀取你需要的所有功能,然后剩下的事情只需要交給RequireJS就行了。為了正確的使用這些功能,你定義的所有模塊都需要使用RequireJS的API,否者它不會(huì)像期望的那樣工作。
RequireJS API 存在于RequireJS載入時(shí)創(chuàng)建的命名空間requirejs下。其主要API主要是下面三個(gè)函數(shù):
- define– 該函數(shù)用戶創(chuàng)建模塊。每個(gè)模塊擁有一個(gè)唯一的模塊ID,它被用于RequireJS的運(yùn)行時(shí)函數(shù),define函數(shù)是一個(gè)全局函數(shù),不需要使用requirejs命名空間.
- require– 該函數(shù)用于讀取依賴。同樣它是一個(gè)全局函數(shù),不需要使用requirejs命名空間.
- config– 該函數(shù)用于配置RequireJS.
在后面,我們將教你如果使用這些函數(shù),但首先讓我們先了解下RequireJS的加載流程。
data-main屬性
當(dāng)你下載RequireJS之后,你要做的第一件事情就是理解RequireJS是怎么開(kāi)始工作的。當(dāng)RequireJS被加載的時(shí)候,它會(huì)使用data-main屬性去搜尋一個(gè)腳本文件(它應(yīng)該是與使用src加載RequireJS是相同的腳本)。data-main需要給所有的腳本文件設(shè)置一個(gè)根路徑。根據(jù)這個(gè)根路徑,RequireJS將會(huì)去加載所有相關(guān)的模塊。下面的腳本是一個(gè)使用data-main例子:
<script src="scripts/require.js" data-main="scripts/app.js"></script>
另外一種方式定義根路勁是使用配置函數(shù),后面我們將會(huì)看到。requireJs假設(shè)所有的依賴都是腳本,那么當(dāng)你聲明一個(gè)腳本依賴的時(shí)候你不需要使用.js后綴。
配置函數(shù)
如果你想改變RequireJS的默認(rèn)配置來(lái)使用自己的配置,你可以使用require.configh函數(shù)。config函數(shù)需要傳入一個(gè)可選參數(shù)對(duì)象,這個(gè)可選參數(shù)對(duì)象包括了許多的配置參數(shù)選項(xiàng)。下面是一些你可以使用的配置:
- baseUrl——用于加載模塊的根路徑。
- paths——用于映射不存在根路徑下面的模塊路徑。
- shims——配置在腳本/模塊外面并沒(méi)有使用RequireJS的函數(shù)依賴并且初始化函數(shù)。假設(shè)underscore并沒(méi)有使用 RequireJS定義,但是你還是想通過(guò)RequireJS來(lái)使用它,那么你就需要在配置中把它定義為一個(gè)shim。
- deps——加載依賴關(guān)系數(shù)組
下面是使用配置的一個(gè)例子:
require.config({
//By default load any module IDs from scripts/app
baseUrl: 'scripts/app',
//except, if the module ID starts with "lib"
paths: {
lib: '../lib'
},
// load backbone as a shim
shim: {
'backbone': {
//The underscore script dependency should be loaded before loading backbone.js
deps: ['underscore'],
// use the global 'Backbone' as the module name.
exports: 'Backbone'
}
}
});
在這個(gè)例子中把根路徑設(shè)置為了scripts/app,由lib開(kāi)始的每個(gè)模塊都被配置在scripts/lib文件夾下面,backbone 加載的是一個(gè)shim依賴。
用RequireJS定義模塊
模塊是進(jìn)行了內(nèi)部實(shí)現(xiàn)封裝、暴露接口和合理限制范圍的對(duì)象。ReuqireJS提供了define函數(shù)用于定義模塊。按章慣例每個(gè)Javascript文件只應(yīng)該定義一個(gè)模塊。define函數(shù)接受一個(gè)依賴數(shù)組和一個(gè)包含模塊定義的函數(shù)。通常模塊定義函數(shù)會(huì)把前面的數(shù)組中的依賴模塊按順序做為參數(shù)接收。例如,下面是一個(gè)簡(jiǎn)單的模塊定義:
define(["logger"], function(logger) {
return {
firstName: “John",
lastName: “Black“,
sayHello: function () {
logger.log(‘hello');
}
}
}
);
我們看,一個(gè)包含了logger的模塊依賴數(shù)組被傳給了define函數(shù),該模塊后面會(huì)被調(diào)用。同樣我們看所定義的模塊中有一個(gè)名為logger的參數(shù),它會(huì)被設(shè)置為logger模塊。每一個(gè)模塊都應(yīng)該返回它的API.這個(gè)示例中我們有兩個(gè)屬性(firstName和lastName)和一個(gè)函數(shù)(sayHello)。然后,只要你后面定義的模塊通過(guò)ID來(lái)引用這個(gè)模塊,你就可以使用其暴露的API。
使用require函數(shù)
在RequireJS中另外一個(gè)非常有用的函數(shù)是require函數(shù)。require函數(shù)用于加載模塊依賴但并不會(huì)創(chuàng)建一個(gè)模塊。例如:下面就是使用require定義了能夠使用jQuery的一個(gè)函數(shù)。
require(['jquery'], function ($) {
//jQuery was loaded and can be used now
});
小結(jié)
在這篇文章中我介紹了RequireJS庫(kù),它是我創(chuàng)建每個(gè)Javascript項(xiàng)目都會(huì)用到的庫(kù)函數(shù)之一。它不僅僅用于加載模塊依賴和相關(guān)的命令,RequireJS幫助我們寫(xiě)出模塊化的JavaScript代碼,這非常有利于代碼的可擴(kuò)展性和重用性。
- LABjs、RequireJS、SeaJS的區(qū)別
- SeaJS 與 RequireJS 的差異對(duì)比
- 一篇文章掌握RequireJS常用知識(shí)
- RequireJS入門(mén)一之實(shí)現(xiàn)第一個(gè)例子
- 小心!AngularJS結(jié)合RequireJS做文件合并壓縮的那些坑
- 探索angularjs+requirejs全面實(shí)現(xiàn)按需加載的套路
- 在JavaScript應(yīng)用中使用RequireJS來(lái)實(shí)現(xiàn)延遲加載
- 使用RequireJS優(yōu)化JavaScript引用代碼的方法
- 優(yōu)化RequireJS項(xiàng)目的相關(guān)技巧總結(jié)
- 在Html中使用Requirejs進(jìn)行模塊化開(kāi)發(fā)實(shí)例詳解
- 在ASP.NET MVC項(xiàng)目中使用RequireJS庫(kù)的用法示例
- 使用RequireJS庫(kù)加載JavaScript模塊的實(shí)例教程
相關(guān)文章
javascript 學(xué)習(xí)筆記(一)DOM基本操作
主要是為了使自己更加熟練操作DOM,記錄自己的點(diǎn)滴,規(guī)范自己的代碼!希望大家共同進(jìn)步!2011-04-04
網(wǎng)頁(yè)中CDATA標(biāo)記的說(shuō)明
經(jīng)常在網(wǎng)頁(yè)html代碼中看見(jiàn)這樣的嵌入標(biāo)簽,但實(shí)際使用沒(méi)有用過(guò),特此在記錄下。2010-09-09
javascript學(xué)習(xí)(二)javascript常見(jiàn)問(wèn)題總結(jié)
在js使用過(guò)程中,經(jīng)常會(huì)碰到一些問(wèn)題,本人利用閑暇時(shí)間整理了一些常見(jiàn)問(wèn)題的解決方法,貼出來(lái)和大家分享,有需要的朋友可以參考下2013-01-01
Javascript 實(shí)現(xiàn)簡(jiǎn)單計(jì)算器實(shí)例代碼
這篇文章主要介紹了Javascript 實(shí)現(xiàn)簡(jiǎn)單計(jì)算器實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2016-10-10
你必須知道的JavaScript 變量命名規(guī)則詳解
在編寫(xiě)代碼的時(shí)候難免涉及到變量的命名問(wèn)題,不能只要求變量名的語(yǔ)法正確,而忽略了變量命名對(duì)代碼可讀性的影響2013-05-05
在JavaScript中操作時(shí)間之getMonth()方法的使用
這篇文章主要介紹了在JavaScript中操作時(shí)間之getMonth()方法的使用,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-06-06
Javascript 按位與運(yùn)算符 (&)使用介紹
Javascript 按位與運(yùn)算符 (&),用于對(duì)兩個(gè) 32 位表達(dá)式執(zhí)行按位“與”運(yùn)算,而一般表達(dá)式里面都是十進(jìn)制整數(shù),此時(shí)需要先轉(zhuǎn)換成對(duì)應(yīng)的二進(jìn)制,然后向前加0,補(bǔ)足32位2014-02-02

