如何利用Require.Js管理多頁面站點文件(譯)


英文版地址

最近使用 Require.Js 的時候我發現它確實是一個改善代碼管理的一個好方法。我以前發表Backbone類的文章時曾提到過 Require,但此前,我從未在傳統的多頁面網站內使用到 Require。在多頁面網站里面配置 Require 的過程相當繁瑣,所以我想將教程整理出來幫助那些可能會遇到困惑的朋友們。

 

概述

注意,本文假設你已經熟悉 Require.Js 和基本的配置使用方法,如果不是,建議你先看看官網的手冊

 

創建一個單頁應用 (single-page App) 時,許多人喜歡在發布之前把所有的js文件全部打包編譯為一個文件,可以減少斷斷續續的 http 請求,操作體驗簡潔明快更像 app,同樣的,這種做法增加了首次加載時頁面的量級。

部署多頁面站點的時候,編譯合並所有文件並非一個好方案,因為你不能保證用戶會訪問到每一個頁面,而且加載中的文件會有很多用不到的js,這拖慢了頁面渲染速度,用戶體驗變差。比如說,用戶只是訪問了Contact頁面,那么有必要把About頁面要用到的js給加載一遍嗎?

完美的情景是每一個頁面都有自己的 main 文件用來存放特定頁面的方法,外加一個獨立文件(最好是緩存起來)用來存放公共 Javascript 庫。

例如,你有一個About頁面和一個 Contact 頁面,於是你新建一個 mian-about.js 和一個 main-contact.js,而且假設 mian-about 和 main-contact 都需要 jQuery 和 underscore。這時,不建議把 jQuery 和 underscore 編譯到每一個 main 文件里面,那樣會造成不必要的重復和臃腫,我們只用新建一個包含 jQuery 和 underscore 的 common.js 並且保證它在 mian-*.js 文件之前加載就可以了。下表可以加深理解:

common.js

----------------

js/vendor/jquery.js

js/vendor/underscore.js

 

About

----------------

js/common.js

js/app/main-about.js

 

 

Contact

----------------

js/common.js

js/app/main-contact.js

將那些公用的 js 文件編譯合並到 common.js 后減少了每個頁面的 http 請求,而且,第一個頁面加載完畢,common.js 就可以從瀏覽器緩存里直接讀取了。下面我們再來看一個例子。

 

例子

RequireJS 的作者 James Burke,做了很多有效組織代碼,利用 RequireJS Optimizer 壓縮優化代碼的努力,有些例子是我經常提到的:example-multipage-shim.example-multipage。但我更喜歡用 shim 版本(它支持非 AMD 方式定義的模塊載入)的 RequireJS,因為一個項目里面似乎總有幾個非 AMD 的腳本文件。

 

如果你在用RequireJs創建一個單頁站點,那么你可能會這樣定義你的script標簽:

<!--This sets the baseUrl to the "scripts" directory, and
    loads a script that will have a module ID of 'main'-->
<script data-main="scripts/main.js" src="scripts/require.js"></script>

data-main 屬性可以很方便的用來設置 RequireJs 的 baseUrl property,通常,你也可以在 main.js 里面加上一些配置,比如,你要加載一個第三方的js庫,你要創建一個路徑以便引用。因為模板里的每一個單頁的 mian-* 文件都不同,所以,我們可以把配置信息放在 common.js 里:

 1 //The build will inline common dependencies into this file.
 2 
 3 requirejs.config({
 4   baseUrl: './js',
 5   paths: {
 6     'jquery': 'vendor/jquery',
 7     'bootstrap': 'vendor/bootstrap'
 8   },
 9   shim: {
10     'bootstrap': ['jquery']
11   }
12 });

除了 common.js,我還在 app/models 下創建了BasicModel文件以表明common.js是公用的,並把BasicModel放進common.js里。

 

編譯

編譯之前需要有一個 option.js 來指定哪些文件需要編譯,哪些不需要:

 1 module.exports = {
 2   appDir: 'www',
 3   baseUrl: 'js/',
 4   mainConfigFile: 'www/js/common.js',
 5   dir: 'www-release',
 6   modules: [
 7     {
 8       name: 'common',
 9       include: [
10         'app/models/basicModel',
11         'jquery',
12         'bootstrap'
13       ]
14     },
15     {
16       name: 'app/main-about',
17       exclude: ['common']
18     },
19     {
20       name: 'app/main-contact',
21       exclude: ['common']
22     }
23   ]
24 };

 上面的代碼中,首先把所有的文件用 include 方法包含進來,然后把不需要的文件用 exclude 方法排除出去。RequireJs 會根據 exclude 的參數配置理出嵌套依賴關系並把文件排除掉。因為 bootstrap 已經編譯合並進 common.js 了,所以不需要單獨為 main-about 或 main-contact 再 exclude 掉 bootstrap。

在執行這些操作之前,你需要執行一個 npm 安裝。首先你要確保安裝了 grunt 工具,安裝完成后執行 grunt 命令壓縮打包。如果打包順利完成,會在www-release/build.txt 里看到如下被打包的文件清單:

css/bootstrap-responsive.css
----------------
css/bootstrap-responsive.css

css/bootstrap.css
----------------
css/bootstrap.css

css/style.css
----------------
css/style.css

js/common.js
----------------
js/common.js
js/app/models/basicModel.js
js/vendor/bootstrap.js

js/app/main-about.js
----------------
js/app/models/aboutModel.js
js/app/main-about.js

js/app/main-contact.js
----------------
js/app/models/contactModel.js
js/app/main-contact.js

www-release/common.js 里面試一大塊壓縮后的代碼,代碼里就包含了 BasicModel, Bootstrap, jQuery, and 初始配置代碼。要配置 about.html ,只需要按下面的順序加載文件即可:

 1 <script src="./js/vendor/require.js"></script>
 2 <script type="text/javascript">
 3 // Load common code that includes config,
 4 // then load the app logic for this page.
 5 require(['./js/common'], function (common) {
 6   // ./js/common.js sets the baseUrl to be ./js/
 7   // You can ask for 'app/main-about' here instead
 8   // of './js/app/main-about'
 9   require(['app/main-about']);
10 });
11 </script>

通過層層引入 RequireJs --> common.js --> main-about.js 實現了明晰簡便的代碼管理方式。

謝謝。

 

前端技術文章翻譯QQ群:338353879

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM