RequireJS進階:模塊的優化及配置的詳解

概述

關於RequireJS已經有不少文章介紹過了。這個工具能夠將你的JavaScript代碼輕易的分割成苦幹個模塊(module)而且保持你的代碼模塊化與易維護性。這樣,你將得到一些具備互相依賴關係的JavaScript文件。僅僅須要在你的HTML文檔中引用一個基於RequireJS的腳本文件,全部必須的文件都將會被自動引用到這個頁面上.javascript

可是,在生產環境中將全部的JavaScript文件分離,這是一個很差的作法。這會致使不少次請求(requests),即便這個些文件都很小,也會浪費不少時間。 能夠經過合併這些腳本文件,以減小請求的次數達到節省加載時間的目的。
另外一種節省加載時間的技巧是縮小這些被加載文件的大小,相對小一些的文件會傳輸的更快一些。這個過程叫做最小化 (minification) ,它是經過當心的改變腳本文件的代碼結構而且不改變代碼的形爲(behavior)和功能(functionality)來實現的。例如這些:去除沒必要要的空格,縮短(mangling,或都壓縮)變量(variables)名與函數(methods,或者叫方法)名,等等。這種合併並壓縮文件的過程叫作代碼優化( optimization)。這種方法除了用於優化(optimization)JavaScript文件,一樣適用於CSS文件的優化。css

RequireJS有兩個主要方法(method): define()和require()。這兩個方法基本上擁有相同的定義(declaration) 而且它們都知道如何加載的依賴關係,而後執行一個回調函數(callback function)。與require()不一樣的是, define()用來存儲代碼做爲一個已命名的模塊。 所以define()的回調函數須要有一個返回值做爲這個模塊定義。這些相似被定義的模塊叫做AMD (Asynchronous Module Definition,異步模塊定義)。html

下面經過一個示例講解如何優化RequireJS項目。(這段話來自下面的參考鏈接)java

所需環境

Node.js、r.js、RequireJS、以及示例程序,示例程序的下載地址爲:http://www.webdeveasy.com/code/optimize-requirejs-projects/todo-mvc.zipnode

配置參數介紹

涉及的操做請能夠參考上面的示例,本文的主要目的主要是經過示例來說解配置參數的使用。git

appDir

appDir: './'

應用程序的頂級目錄,若是這個選項被開啓的話,那麼你的腳本文件是這個目錄路徑下的一個子目錄。這個是個可選項。若是沒有設置的話,則經過baseUrl這個參數下的錨點來查找文件(?)。若是設置了該選項的話,那麼這個路徑下的全部文件都會被複制到dir指定的輸出目錄,而且baseUrl這個目錄的路徑是相對於該路徑。github

baseUrl

baseUrl: './js'

默認狀況下,因此的模塊都相對於這個路徑存在(有人稱爲腳本的跟路徑),若是baseUrl沒有明確指定的話,那麼全部的模塊路徑都相對與build構建文件的路徑。若是appDir已設置,那麼baseUrl 的路徑是相對與appDirweb

mainConfigFile

mainConfigFile: '../some/path/to/main.js'

RequireJS的主配置文件。這裏要區分配置文件和入口文件的區別,示例中的main.js即包含配置文件同時又是文件的入口文件。segmentfault

paths

paths: {
        "foo.bar": "../scripts/foo/bar",
        "baz": "../another/path/baz"
    },

參見: RequireJS進階:配置文件的學習跨域

map

map: {},

參見: RequireJS進階:配置文件的學習

packages

packages: [],

參見: RequireJS進階:配置文件的學習

dir

dir: "../some/path"

文件輸出的頂級目錄。若是沒有指定的話,默認會建立一個「build」目錄在build文件的路徑中。全部相對路徑是相對於構建文件。

keepBuildDir

keepBuildDir: true

在 RequireJS 2.0.2 中,輸出目錄的全部資源會在 build 前被刪除。值爲 true 時 rebuild 更快,但某些特殊情景下可能會出現沒法預料的異常

shim

shim: {},

參見: RequireJS進階:配置文件的學習

wrapShim

wrapShim: false,

禁止非模塊包裹define函數。

locale

locale: "en-us",

國際化配置設置。

optimize

optimize: "uglify",

優化腳本文件的方式。值只能取下面的任何值中的一個。

  • "uglify": (default) uses UglifyJS to minify the code.

  • "uglify2": in version 2.1.2+. Uses UglifyJS2.

  • "closure": uses Google's Closure Compiler in simple optimizationmode to minify the code. Only available if running the optimizer using Java.

  • "closure.keepLines": Same as closure option, but keeps line returns in the minified files.

  • "none": no minification will be done.

skipDirOptimize

skipDirOptimize: false,

當設置爲true時,優化器將會跳過非構建中被約束的JS文件。

generateSourceMaps

generateSourceMaps: false,

是否生成SourceMaps文件,什麼是SourceMaps,參考SourceMaps

normalizeDirDefines

normalizeDirDefines: "skip",

2.1.11中:若是dir被聲明且不爲」none」,而且skipDirOptimize 爲false,一般全部的JS文件都會被壓縮,這個值自動設置爲」all」。爲了讓JS文件可以在壓縮過正確執行,優化器會加一層define()調用而且會插入一個依賴數組。固然,這樣會有一點點慢若是有不少文件或者有大文件的時候。因此,設置該參數爲」skip」這個過程就不會執行,若是optimize設置爲」none」也同樣。若是你想手動設置值的話:

  • 優化後:若是你打算壓縮沒在modules聲明的JS文件,在優化器執行事後,你應該設置這個值爲」all」

  • 優化中:但在動態加載事後,你想作一個會文件優化,但不打算在動態加載這些文件能夠設置成」skip」

最後:全部生成的文件(不管在不在modules裏聲明過)自動標準化

uglify

uglify: {
        toplevel: true,
        ascii_only: true,
        beautify: true,
        max_line_length: 1000,

        //How to pass uglifyjs defined symbols for AST symbol replacement,
        //see "defines" options for ast_mangle in the uglifys docs.
        defines: {
            DEBUG: ['name', 'false']
        },

        //Custom value supported by r.js but done differently
        //in uglifyjs directly:
        //Skip the processor.ast_mangle() part of the uglify call (r.js 2.0.5+)
        no_mangle: true
    },

使用UglifyJS進行代碼壓縮,具體參數配置可見UglifyJS

uglify2

uglify2: {
        //Example of a specialized config. If you are fine
        //with the default options, no need to specify
        //any of these properties.
        output: {
            beautify: true
        },
        compress: {
            sequences: false,
            global_defs: {
                DEBUG: false
            }
        },
        warnings: true,
        mangle: false
    },

使用UglifyJS2進行代碼壓縮, 具體參數配置可見UglifyJS2

closure

closure: {
    CompilerOptions: {},
    CompilationLevel: 'SIMPLE_OPTIMIZATIONS',
    loggingLevel: 'WARNING'
},

若是用Closure Compiler優化,這個參數能夠用來配置Closure Compiler,詳細請看Closure Compiler的文檔

optimizeCss

optimizeCss: "standard.keepLines.keepWhitespace",

是否優化CSS文件,以那種方式優化。

  • "standard": @import inlining and removal of comments, unnecessary whitespace and line returns.Removing line returns may have problems in IE, depending on the type of CSS.
  • "standard.keepLines": like "standard" but keeps line returns.
  • "none": skip CSS optimizations.
  • "standard.keepComments": keeps the file comments, but removes linereturns. (r.js 1.0.8+)
  • "standard.keepComments.keepLines": keeps the file comments and linereturns. (r.js 1.0.8+)
  • "standard.keepWhitespace": like "standard" but keeps unnecessary whitespace.

cssImportIgnore

cssImportIgnore: null,

是否忽略 CSS 資源文件中的 @import 指令

cssIn

cssIn: "path/to/main.css",

通常用於命令行,可將多個 CSS 資源文件打包成單個 CSS 文件

out

out: "path/to/css-optimized.css",

通常用於命令行,可將多個 CSS 資源文件打包成單個 CSS 文件

cssPrefix

cssPrefix: "",

若是」out」和」cssIn」不是同一目錄,而且在cssIn文件裏面有url()相對目錄的,用這個去設置URL前置。僅僅在優化後URL不正確的狀況下使用。

inlineText

inlineText: true,

處理全部的文本資源依賴項,從而避免爲加載資源而產生的大量單獨xhr請求

useStrict

useStrict: false,

是否開啓嚴格模式, 因爲不少瀏覽器不支持 ES5 的嚴格模式,故此配置默認值爲 false

pragmas

pragmas: {
    fooExclude: true
},

指定生成編譯指示。若是源文件包含相似以下注釋:>>excludeStart(「fooExlude」,pragmas.fooExclude); >>excludeEnd(「fooExclude」);那麼以//>>開頭的註釋就是編譯指示。excludeStart/excludeEnd和includeStart/includeEnd起做用,在includeStart或excludeStart中的編譯指示值將參與計算來判斷Start和End以前的編譯指示是include仍是exclude。若是你能夠選擇用」has」或編譯指示,建議用」has」代替。 編譯指示比較難於閱讀,可是它在對代碼移除上比較靈活。基於」has」的代碼必須遵照JavaScript規則。編譯指示還能夠在未壓縮的代碼中刪除代碼,而」has」只能經過UglifyJS或者Closure Compiler來作。

pragmasOnSave

pragmasOnSave: {
        //Just an example
        excludeCoffeeScript: true
    },

和」pragmas」同樣,但只能在文件保存的優化階段應用一次。」pragmas」能夠同時在依賴映射和文件保存優化階段應用。有些」pragmas」可能不會在依賴映射時被執行,例如在CoffeeScript的loader插件中,只想CoffeeScript作依賴映射,可是一旦這個文件被保存爲一個javascript文件,CoffeeScript compiler就沒用了。那樣的話,pragmasOnSave就會用於在保存期排除編譯代碼。

has

has: {
        'function-bind': true,
        'string-trim': false
    },

使用」has」容許trimming代碼樹。基於js的特徵檢測:https://github.com/phiggins42/has.js。代碼樹修飾僅僅在使用UglifyJS或Closure Compiler壓縮時發生。更多請見:http://requirejs.org/docs/optimization.html#hasjs

hasOnSave

hasOnSave: {
        'function-bind': true,
        'string-trim': false
    },

和pragmasOnSave相似。

namespace

namespace: 'foo',

命名空間,完整實例能夠參考 http://requirejs.org/docs/faq-advanced.html#rename

skipPragmas

skipPragmas: false,

跳過執行pragmas

skipModuleInsertion

skipModuleInsertion: false,

若是是false,文件就不會用define()來定義模塊而是用一個define()佔位符插入其中。另外,require.pause/resume調用也會被插入。設置爲」true」來避免。這個參數用在你不是用require()來建立項目或者寫js文件,可是又想使用RquireJS的優化工具來合併模塊是很是有用的。

stubModules

stubModules: ['text', 'bar'],

將模塊排除在優化文件以外。

optimizeAllPluginResources

optimizeAllPluginResources: false,

若是不是一個文件的優化,描述輸出目錄的全部.js文件的插件依賴,若是這個插件支持優化成爲一個單獨的文件,就優化它。多是一個比較慢的優化過程。僅僅在有些插件用了像XMLHttpRequest不支持跨域,而且生成的代碼會被放在另外一個域名。

findNestedDependencies

findNestedDependencies: false,

尋找require()裏面的require或define調用的依賴。默認爲false是由於這些資源應該被認爲是動態加載或者實時調用的。固然,有些優化場景也須要將它們合併在一塊兒。

removeCombined

removeCombined: false

若是設置爲true,在輸出目錄將會刪除掉已經合併了的文件

modules

modules: [
        //Just specifying a module name means that module will be converted into
        //a built file that contains all of its dependencies. If that module or any
        //of its dependencies includes i18n bundles, they may not be included in the
        //built file unless the locale: section is set above.
        {
            name: "foo/bar/bop",

            //create: true can be used to create the module layer at the given
            //name, if it does not already exist in the source location. If
            //there is a module at the source location with this name, then
            //create: true is superfluous.
            create: true,

            //For build profiles that contain more than one modules entry,
            //allow overrides for the properties that set for the whole build,
            //for example a different set of pragmas for this module.
            //The override's value is an object that can
            //contain any of the other build options in this file.
            override: {
                pragmas: {
                    fooExclude: true
                }
            }
        },

        //This module entry combines all the dependencies of foo/bar/bop and foo/bar/bee
        //and any of their dependencies into one file.
        {
            name: "foo/bar/bop",
            include: ["foo/bar/bee"]
        },

        //This module entry combines all the dependencies of foo/bar/bip into one file,
        //but excludes foo/bar/bop and its dependencies from the built file. If you want
        //to exclude a module that is also another module being optimized, it is more
        //efficient if you define that module optimization entry before using it
        //in an exclude array.
        {
            name: "foo/bar/bip",
            exclude: [
                "foo/bar/bop"
            ]
        },

        //This module entry shows how to specify a specific module be excluded
        //from the built module file. excludeShallow means just exclude that
        //specific module, but if that module has nested dependencies that are
        //part of the built file, keep them in there. This is useful during
        //development when you want to have a fast bundled set of modules, but
        //just develop/debug one or two modules at a time.
        {
            name: "foo/bar/bin",
            excludeShallow: [
                "foo/bar/bot"
            ]
        },

        //This module entry shows the use insertRequire (first available in 2.0):
        {
            name: "foo/baz",
            insertRequire: ["foo/baz"]
        }
    ],

列出要優化的模塊。若是有依賴i18n的,只有root層會被包含進來除非locale:塊在上面被聲明過。

①僅定義模塊會被轉換成一個生成目標文件的名字,包含全部依賴項。i18n依賴同上,

create:true可用來生成在源文件目錄不存在的給定模塊名。若是源文件目錄已經存在一個相同名稱的模塊,create參數就沒用了;

override:能夠重寫全局的pragmas

②這個模塊聲明編譯foo/bar/bop的全部依賴和foo/bar/bee及其全部依賴

③編譯全部foo/bar/bip的依賴到一個文件,可是排除foo/bar/bop和它的全部依賴文件,若是想把另外一個模塊單獨優化,這是一個很好用的方法

④excludeShallow只排除掉這個模塊,可是若是輸出模塊的依賴和它有相同就保留不排除。

⑤這個模塊聲明表示用insertRequire(在2.0中新加入)

insertRequire

insertRequire: ['foo/bar/bop'],

若是目標模塊在頂層級只調用了define沒有調用require(),而且輸出文件在data-main中使用,若是頂層沒有require,就不會有任何模塊被加載。定義insertRequire在文件尾部來執行其它模塊,更多參見:https://github.com/jrburke/almond

name

name: "foo/bar/bop",

include

include: ["foo/bar/bee"],

insertRequire

insertRequire: ['foo/bar/bop'],

out

out: "path/to/optimized-file.js",

若是隻優化一個模塊(和它的依賴項),並且是生成一個單文件,你能夠在行內定義模塊的選項,以代替modules參數的定義方式,」exclude」, 「excludeShallow」, 「include」和」insertRquire」均可以以兄弟屬性的方式定義。

deps

deps: ["foo/bar/bee"],

「include」的替換方案。通常用requirejs.config()來定義並用mainConfigFile引入。

out

out: function (text, sourceMapText) {
        //Do what you want with the optimized text here.
        //Starting in 2.1.10, if generateSourceMaps was set to true
        //and optimize: 'uglify2' was used, then the second argument
        //to this function, sourceMapText, will be the text of the source map.
    },

在2.0,」out」能夠是一個函數, 對單個JS文件優化能夠調用requirejs.optimize(), 用out函數表示優化事後的內容不會被寫到磁盤,而是傳遞給out函數

out

out: 「stdout」

在2.0.12+, 設置」out」爲」stdout」, 優化輸出會寫到STDOUT,這對於r.js整合其它命令行工具頗有用。爲了不額外的輸出」logLevel: 4」應該被使用。

wrap

wrap: {
    start: "(function() {",
    end: "}());"
},

wrap任何東西在start和end之間,用於define/require不是全局的狀況下,在end裏能夠暴露全局對象在文件中。

wrap

wrap: true,

wrap的另外一種方式,默認是(function() { + content + }())

wrap

wrap: {
    startFile: "parts/start.frag",
    endFile: "parts/end.frag"
},

用文件來wrap

wrap

wrap: {
    startFile: ["parts/startOne.frag", "parts/startTwo.frag"],
    endFile: ["parts/endOne.frag", "parts/endTwo.frag"]
},

多個文件的wrap

fileExclusionRegExp

fileExclusionRegExp: /^./,
跳過任何以.開頭的目錄和文件,好比.files, .htaccess等

preserveLicenseComments

preserveLicenseComments: true,

默認註釋有受權在裏面。固然,在大項目生成時,文件比較多,註釋也比較多,這樣能夠把全部註釋寫在文件的頂部。

logLevel

logLevel: 0

設置logLevel。

TRACE: 0,

INFO: 1

WARN: 2

ERROR: 3

SILENT: 4

throwWhen

throwWhen: {
  optimize: true
}

在2.1.3,有些狀況下當錯誤發生時不會拋出異常並中止優化,你可能想讓優化器在某些錯誤發生時中止,就可使用這個參數

onBuildRead

onBuildRead: function (moduleName, path, contents) {
    //Always return a value.
    //This is just a contrived example.
    return contents.replace(/foo/g, 'bar');
},

當每一個文件被讀取的時候調用這個方法來改變文件內容

onBuildWrite

onBuildWrite: function (moduleName, path, contents) {
    //Always return a value.
    //This is just a contrived example.
    return contents.replace(/bar/g, 'foo');
},

容許在寫入目標文件前執行方法改變內容

onModuleBundleComplete

onModuleBundleComplete: function (data) {
    /*
    data.name: the bundle name.
    data.path: the bundle path relative to the output directory.
    data.included: an array of items included in the build bundle.
    If a file path, it is relative to the output directory. Loader
    plugin IDs are also included in this array, but depending
    on the plugin, may or may not have something inlined in the
    module bundle.
    */
},

每一個JS模塊集完成後執行。 模塊集是指一個modules數組項。

rawText

rawText: {
    'some/id': 'define(["another/id"], function () {});'
},

在2.1.3,種子raw text是模塊ID的列表。這些文本內容用於代替模塊的文件IO調用。用於模塊ID是基於用戶動態輸入的狀況,在網頁生成工具中經常使用。

cjsTranslate

cjsTranslate: true,

在2.0.2中。若是爲true, 優化器會添加define(require, exports, module) {});包裹每個沒有調用define()的文件。

useSourceUrl

useSourceUrl: true,

在2.0.2,有點實驗性質。每個模塊集最後都會添加一段//# sourceUrl的註釋。

waitSeconds

waitSeconds: 7

參見: RequireJS進階:配置文件的學習

skipSemiColonInsertion

skipSemiColonInsertion: false

在2.1.9,一般r.js插入一個分號在文件末尾,若是沒有的話。

keepAmdefine

keepAmdefine: false

在2.1.10, 若是是true,就不會刪除amdefine,詳情見:https://github.com/jrburke/amdefine

allowSourceOverwrites

allowSourceOverwrites: false

在2.1.11中, 做爲修復BUG的一部分https://github.com/jrburke/r.js/issues/444。設置爲true就容許源代碼進行重寫覆蓋。固然,爲了安全起見,請正確配置,好比你可能想設置」keepBuildDir」爲true。

幫助文檔

參考連接:http://jiongks.sinaapp.com/blog/build-any-web-project-with-requirejs-optimizer/
英文文檔(r.js):https://github.com/jrburke/r.js/blob/master/build/example.build.js
參考連接:http://www.oschina.net/translate/optimize-requirejs-projects
參考連接:http://www.cnblogs.com/haoliang/p/3656475.html
參考連接:http://www.yfznw.com/node/22

PS:若是涉及侵權或者文章有錯誤,請及時通知。

相關文章
相關標籤/搜索