此篇範例不適用於RequireJS 2.0,請參考後篇文章
如果有用Backbone在寫網頁的人,應該都會看過有人拿RequireJS來做Asynchronous Module Definition(AMD)把Backbone的Model、View、Cellection還有Router等等都拆開成獨立的Module檔案,這篇文章主要就是要講解如何用RequireJS提供的Optimizer,也就是r.js來壓縮打包這些模組成單一檔案,以便在實際網站上線環境佈署。
首先要先講一下雖然jQuery 1.7之後加入了對AMD的支援,但是Backbone和Underscore卻反而移掉了這個部份,這也讓力推AMD的Dojo Foundation跟DocumentCloud槓上,另外fork出了支援AMD的版本來維護。如果使用不支援AMD的原版,就必須要對這個問題多加處理,而處理的方法可能各有不同(例如使用RequireJS的order外掛之類的),這裡就直接使用amdjs提供的改進版本來做示範。
一開始先在網頁中使用RequireJS,以及設定引入的第一個檔案:
<script data-main="/javascript/main.js" src="/javascript/require.js"></script>
接著在main.js中設定好相關路徑:
require({
paths: {
jquery: 'lib/jquery-1.7.2.min',
underscore: 'lib/underscore-min',
backbone: 'lib/backbone-min',
templates: '../templates'
},
priority: ['jquery']
}, [
'app',
'lib/jquery.serialize'
], function(
App
) {
App.start();
});
重點是設定priority讓RequireJS先載入jQuery,讓載入後面的jQuery相關外掛時不會出錯。再來是app.js:
define([
'jquery',
'underscore',
'backbone',
'router'
], function(
$,
_,
Backbone,
Router
) {
'use strict';
var App = {};
App.start = function() {
App.router = new Router;
Backbone.history.start();
};
return App;
});
以上大概就是一個標準的Backbone + RequireJS使用樣版。
重頭戲來了,工具先準備好,nodeJS跟npm裝好後再:
sudo npm -g install requirejs
安裝好r.js後,在專案底下新增一個build.js來描述處理的相關參數:
{
baseUrl: 'javascript',
dir: 'scripts',
modules: [
{
name: 'main'
}
],
paths: {
jquery: 'lib/jquery-1.7.2.min',
underscore: 'lib/underscore-min',
backbone: 'lib/backbone-min',
templates: '../templates'
}
}
baseUrl是要處理的目標路徑,dir則是設定輸出的新增資料夾名稱,得跟前面不一樣以免原始檔案被覆蓋,modules則是要處理的模組檔名,最後但也很重要的是要把paths在這裡也宣告一次。此外如果不想讓它一併處理CSS,可以設optimizeCss: none
,更完整的設定項目可以看r.js給的範例。
接著一邊大喊「指揮艇,組合!」一邊帥氣地敲下指令:
r.js -o build.js
就可以在設定的輸出資料夾裡看到輸出的成果了。
透過這樣的處理,現在網站只剩require.js和main.js兩個檔案要載入了,那麼有沒有辦法連require.js也一起合併進來呢?是有這樣的作法,不過requireJS的檔案壓縮後只剩10幾Kb,如果要再精打細算,可以用較輕巧的almond.js來合併,將下載的almond.js重新命名為script.js然後擺在原本未處理前的main.js旁邊,再修改剛剛的build.js,在modules的部份:
modules: [
{
name: "script",
include: ['main']
}
],
這個新的鍊成陣使用include設定讓script.js同時引入main的內容再做最佳化處理。這樣在網頁的部份就只要載入一份最佳化後的script.js就可以了:
<script src="script.js"></script>
使用almond代替require有一些使用上的限制,畢竟壓縮後不到2Kb,有不少RequireJS的功能無法支援,可以看Github專案頁面的說明,例如它就無法處理A模組定義引用B模組,同時B模組也定義引用A模組的情況,不過會寫成這樣,應該要先檢討專案的架構跟寫法才是。
要是遇上真的無法使用almond代替的場合,是不能把require.js丟進去用的,因為r.js會自動略過requireJS不處理,這樣只能把自己把壓縮後的require.js串接到壓縮後的main.js前面了。
延伸閱讀:
Module, AMD, RequireJS
初探 Require.JS
利用 RequireJs 將 Backbone.js 程式模組化
One reply on “Use RequireJS Optimizer to deploy Backbone project”
[…] shim 這項設定,大大提升引入不支援AMD定義的模組方便性,以下開始講解前篇文章的範例該如何做升級修改。 首先來看 […]