require.js初試(with angular & optimization)

若是你只是想找一款稱手的js加載器,能夠參考這篇js loader benchmarks(http://artzstudio.com/files/Boot/test/benchmarks/script.html),即使這篇文章已經例舉得夠多的了,仍是沒有涵蓋到不少已經廣爲使用的庫,若是要跟你本身熟悉的庫來作對比,能夠仿照文中的例子自行對比。
javascript

我要說的是require.js,能夠做爲加載器來使用,但它誕生的目的不是爲了異步加載腳本,而是爲了模塊化,同時也就不會污染global。簡單作了一個與angular.js結合的demo。
關於require.js,能夠參考阮一峯的《javascript模塊塊編程》,在此給出介紹require.js的一節http://www.ruanyifeng.com/blog/2012/11/require_js.html
官方api就不用說了:http://requirejs.org/docs/api.html
同時還支持壓縮優化:http://requirejs.org/docs/optimization.htmlcss

本文練習使用require.js和angular,以及利用r.js來進行壓縮html


1,結構

--index.html
--js
    --main.js(入口)
    --app(業務代碼,angular相關代碼)
        ----app.js
        ----controllers.js
        ----directives.js
        ----filters.js
        ----services.js
    --test(業務代碼,測試用,跟app做用差很少,此處測把不一樣的程序加載同一插件的不一樣版本)
        ----plugin.1.0.js
        ----plugin.1.2.js
        ----newapp.js
        ----oldapp.js
    --vendor(提供程序,angular,jquery等,若是引用了underscore, backbone固然也應該是這個目錄)
        ----jquery.js
        ----angular.js
--partials
    --partial1.html
    --partial2.html
--css
    --app.css


固然,大致上,是跟這個seed同樣的:https://github.com/tnajdek/angular-requirejs-seed
java

2,傳統寫法


<script src="js/vendor/angular.js"></script>
<script src="js/app/app.js"></script>
<script src="js/app/services.js"></script>
<script src="js/app/controllers.js"></script>
<script src="js/app/filters.js"></script>
<script src="js/app/directives.js"></script>

3,require.js的寫法

能夠這麼寫:
<script type="text/javascript" data-main="js/main" src="js/vendor/require.js"></script> 
也能夠把main.js的內容直接寫到緊要require.js引用的地方,第一個被發現的requirejs({}), requirejs.config({}), require({}), 或 require.config({})會被認做配置文件:
<script type="text/javascript" src="js/vendor/require.js"></script>
  <script type=""text/javascript">
    require.config({
      //same as main.js
    });
    require(['main']);
  </script>

4,引入require後angular的寫法:

//觀察一下define的用法就基本明白了

//聲明依賴於service, filter, directive的app級別的moudle
define(['lib/angular'],function(angular){
    angular.module('myApp', ['filters', 'services', 'directives', 'controllers']).
      config(['$routeProvider', function($routeProvider) {
        $routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
        $routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
        $routeProvider.otherwise({redirectTo: '/view1'});
      }]);
});

//srvices.js

define(['lib/angular'],function(angular){
// Demonstrate how to register services
// In this case it is a simple value service.
angular.module('services', []).
  value('version', '0.1');
  // factory('version',function(){return '0.3';});
});

//filters.js

define(['lib/angular'],function(angular){
	angular.module('directives', []).
	  directive('appVersion', ['version', function(version) {
	    return function(scope, elm, attrs) {
	      elm.text(version);
	    };
	  }]);
});

//controllers.js

define(['lib/angular'],function(angular){
	angular.module('controllers', []).
	  controller('MyCtrl1', [function() {

	  }])
	  .controller('MyCtrl2', [function() {

	  }]);
});

5,製做main.js文件

require.config({
    baseUrl:'js/app',//配置默認路徑,
    paths:{
        'lib':'../vendor',//配置了baseUrl後,顯然不處於其子目錄的路徑是須要額外配置的
        'test':'../test',
        'main':'../main'
    },
    shim:{
        'lib/angular':{exports:'angular'}//不支持AMD的腳本用shim的方式加載
    },
    map:{
        //一個項目裏用了同一插件不一樣版本的狀況用map來映射
        '*':{'plugin':'test/plugin.1.2'},
        'test/oldapp':{'plugin':'test/plugin.1.0'}
    }
});

require([
    'lib/angular',
    'test/newapp',
    'test/oldapp',
    'app',
    'services',
    'controllers',
    'filters',
    'directives'
],function(angular){    
    //此處引用了所需的全部模塊,而且只作了一件事,用angular把頁面驅動起來。
    angular.bootstrap(document,['myApp']);
});

寫的過程當中邊看文檔邊作了不少嘗試,總之成品就是上面那樣的了,建議仍是多讀讀文檔,講解了不少須要注意的地方。

6,合併/壓縮js文件

一樣,細讀文檔,你的電腦須要有node環境,同時下載了r.js,測試過程略過,看我測試經過的成品吧:
//build.js,置於js根目錄下
({
    baseUrl:'app',
    paths:{requireLib:'../vendor/require'},
    include:'requireLib',//若是須要把require也壓進去(這樣整個項目只須要一個js文件了),設置其path,並
    name:'main',
    out:'main-built-require.js',//輸出的文件名
    optimize:'none',//註釋掉此行便可同時把合併後的js文件壓縮
    mainConfigFile:'main.js'//用已寫好的main.js文件來處理模塊依賴關係
})

運行命令(由於r.js在整個項目以外,build.js位於/js/目錄下,因此跳兩層跳出去:

node ../../r.js -o app.build.jsnode


同級目錄順利生成main-built-require.js

7,壓縮整個項目

還沒深刻研究,如下這個腳本能夠把每一個js和css進行壓縮:
//app.build.js
({
    appDir:'../',//以本文件爲起點,配置項目根目錄
    dir:'../../appdirectory-build',//爲了避免影響源碼,輸出到同級目錄
    mainConfigFile:'main.js'//一樣,入口配置文件的位置
})

一樣的命令:

node ../../r.js -o app.build.jsjquery


看輸出,很明顯地提示了在用Uglifying壓縮了每個js文件,以及css文件(忽視對web-server.js的報錯,那是爲了用node把網站跑起來寫的一個腳本,與本例無關)
F:\temp\require_angular\js>node ../../r.js -o app.build.js
Optimizing (standard.keepLines) CSS file: F:/temp/appdirectory-build/css/app.css

Uglifying file: F:/temp/appdirectory-build/js/app/app.js
Uglifying file: F:/temp/appdirectory-build/js/app/controllers.js
Uglifying file: F:/temp/appdirectory-build/js/app/directives.js
Uglifying file: F:/temp/appdirectory-build/js/app/filters.js
Uglifying file: F:/temp/appdirectory-build/js/app/my.js
Uglifying file: F:/temp/appdirectory-build/js/app/services.js
Uglifying file: F:/temp/appdirectory-build/js/app.build.js
Uglifying file: F:/temp/appdirectory-build/js/build.js
Uglifying file: F:/temp/appdirectory-build/js/main-built-require.js
Uglifying file: F:/temp/appdirectory-build/js/main-built-require2.js
Uglifying file: F:/temp/appdirectory-build/js/main-built.js
Uglifying file: F:/temp/appdirectory-build/js/main.js
Uglifying file: F:/temp/appdirectory-build/js/test/newapp.js
Uglifying file: F:/temp/appdirectory-build/js/test/oldapp.js
Uglifying file: F:/temp/appdirectory-build/js/test/plugin.1.0.js
Uglifying file: F:/temp/appdirectory-build/js/test/plugin.1.2.js
Uglifying file: F:/temp/appdirectory-build/js/vendor/angular.js
Uglifying file: F:/temp/appdirectory-build/js/vendor/require.js
toTransport skipping F:/temp/appdirectory-build/web-server.js: Error: Line 1: Un
expected token ILLEGAL
Error: Cannot parse file: F:/temp/appdirectory-build/web-server.js for comments.
 Skipping it. Error is:
Error: Line 1: Unexpected token ILLEGAL

css/app.css
----------------
css/app.css

8,示例代碼下載

zip文件svn地址git

相關文章
相關標籤/搜索