RequireJS Optimizer 是 RequireJS 自帶的前端優化工具,可以對 RequireJS 項目中的 JavaScript & CSS 代碼使用 UglifyJS 或者 Closure Compiler 進行壓縮合並。這篇文章介紹RequireJS Optimizer 的使用和配置方法,幫助大家解決使用中碰到的問題。
RequireJS Optimizer 對腳本的優化支持目前流行的 UglifyJS 和 Closure Compiler 兩種壓縮方式,UglifyJS 需要 NodeJS 環境支持,而 Closure Compiler 則需要 Java 環境。這篇文章是以運行於 NodeJS 的 UglifyJS 來優化的,這也是 RequireJS Optimizer 默認的壓縮方法。
首頁需要安裝 Node 0.4.0 或更高版本,然后下載 r.js,下載好以后就可以在命令行里對前端代碼進行優化了。r.js 的參數傳遞使用方式,一是直接加在命令行后面,如下:
node r.js -o baseUrl=. paths.jquery=some/other/jquery name=main out=main-built.js
二是新建一個配置文件,例如 build.js(推薦使用這種方式),這樣配置更方便,如下:
node r.js -o build.js
build.js 的配置代碼如下:
{ baseUrl: "../js", dir: "../dist", optimize: "uglify", optimizeCss: "standard.keepLines", mainConfigFile: "../js/main.js", removeCombined: true, fileExclusionRegExp: /^\./, modules: [ { name: "app/dispatcher", }, { name: "app/in-storage", exclude: [ "jquery", "app/common", "pkg/DatePicker/app" ] } ] }
基本參數介紹
appDir
應用程序的最頂層目錄。可選的,如果設置了的話,r.js 會認為腳本在這個路徑的子目錄中,應用程序的文件都會被拷貝到輸出目錄(dir 定義的路徑)。如果不設置,則使用下面的 baseUrl 路徑。
baseUrl
默認情況下,所有的模塊都是相對於這個路徑的。如果沒有設置,則模塊的加載是相對於 build 文件所在的目錄。另外,如果設置了appDir,那么 baseUrl 應該定義為相對於 appDir 的路徑。
dir
輸出目錄的路徑。如果不設置,則默認為和 build 文件同級的 build 目錄。
optimize
JavaScript 代碼優化方式。可設置的值:
- "uglify:使用 UglifyJS 壓縮代碼,默認值;
- "uglify2":使用 2.1.2+ 版本進行壓縮;
- "closure": 使用 Google's Closure Compiler 進行壓縮合並,需要 Java 環境;
- "closure.keepLines":使用 Closure Compiler 進行壓縮合並並保留換行;
- "none":不做壓縮合並;
optimizeCss
CSS 代碼優化方式,可選的值有:
- "standard":標准的壓縮方式;
- "standard.keepLines":保留換行;
- "standard.keepComments":保留注釋;
- "standard.keepComments.keepLines":保留換行;
- "none":不壓縮;
mainConfigFile
如果不想重復定義的話,可以使用這個參數配置 RequireJS 的配置文件路徑。
removeCombined
刪除之前壓縮合並的文件,默認值 false。
fileExclusionRegExp
要排除的文件的正則匹配的表達式。
modules
定義要被優化的模塊數組。每一項是模塊優化的配置,常用的幾個參數如下:
name:模塊名;
create:如果不存在,是否創建。默認 false;
include:額外引入的模塊,和 name 定義的模塊一起壓縮合並;
exclude:要排除的模塊。有些模塊有公共的依賴模塊,在合並的時候每個都會壓縮進去,例如一些基礎庫。使用 exclude 就可以把這些模塊在壓縮在一個更早之前加載的模塊中,其它模塊不用重復引入。
其它事項
RequireJS 配置也可以放到 RequireJS Optimizer 配置文件里面,例如:
{ baseUrl: "../js", dir: "../dist", optimize: "uglify", optimizeCss: "standard.keepLines", removeCombined: true, fileExclusionRegExp: /^\./, modules: [ { name: "app/dispatcher", }, { name: "app/in-storage", exclude: [ "jquery", "app/common", "pkg/DatePicker/app" ] } ], paths: { jquery: 'lib/jquery', underscore: 'lib/underscore', backbone: 'lib/backbone/backbone', backboneLocalstorage: 'lib/backbone/backbone.localStorage', text: 'lib/require/text' }, shim: { underscore: { exports: '_' }, backbone: { deps: [ 'underscore', 'jquery' ], exports: 'Backbone' }, backboneLocalstorage: { deps: ['backbone'], exports: 'Store' } } }
RequireJS Optimizer 的配置參數還有很多,完整的參數介紹可以看這里:
https://github.com/jrburke/r.js/blob/master/build/example.build.js
為方便運行,可以新建一個批處理文件:
@echo off echo build... e: cd E:\SCM\SRC\scm-html\new-scm-html\tools node r.js -o build.js echo Press any key to exit! echo. & pause
注意事項:RequireJS Optimizer 只支持使用 require 和 define 語法定義的模塊,因此下面這種通過變量定義的方式是不支持的:
var mods = someCondition ? ['a', 'b'] : ['c', 'd']; require(mods);
而如果是這樣定義則可以:
require(['a', 'b']);
或者:
define(['a', 'b'], function (a, b) {});
進一步優化
使用 r.js 優化后的代碼可以使用 almond 來加載。almond 是一個輕量的 AMD 加載器,提供了最基礎的 AMD API 實現以及模塊加載功能。almond 只有不到 400 行代碼,要比 RequireJS 小很多。可以使用 r.js 把 almond 一起合並到業務代碼的前面,如下:
(function () { //almond will be here //main and its nested dependencies will be here }());
almond 特別適合使用 AMD 的網站或應用,但也有一些限制:
- 所有的模塊編譯為一個文件,沒有動態的加載;
- 所有的模塊都需要在 define() 定義 ID 和依賴,這個 RequireJS Optimizer 會處理;
- 只能有一個 requirejs.config() 或者 require.config() 調用;
- 不能使用 Require JS 多版本功能;
- 不能使用 require.toUrl() 或者 require.nameToUrl();
- 不能使用 packages/packagePaths 配置。
如果你的項目中沒有這些問題的話,可以放心使用 almond 進行加載。