乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      RequireJS和AMD規(guī)范

       看見(jiàn)就非常 2015-04-24

       RequireJS和AMD規(guī)范

      目錄

      概述

      RequireJS是一個(gè)工具庫(kù),主要用于客戶端的模塊管理。它可以讓客戶端的代碼分成一個(gè)個(gè)模塊,實(shí)現(xiàn)異步或動(dòng)態(tài)加載,從而提高代碼的性能和可維護(hù)性。它的模塊管理遵守AMD規(guī)范(Asynchronous Module Definition)。

      RequireJS的基本思想是,通過(guò)define方法,將代碼定義為模塊;通過(guò)require方法,實(shí)現(xiàn)代碼的模塊加載。

      首先,將require.js嵌入網(wǎng)頁(yè),然后就能在網(wǎng)頁(yè)中進(jìn)行模塊化編程了。

      <script data-main="scripts/main" src="scripts/require.js"></script>

      上面代碼的data-main屬性不可省略,用于指定主代碼所在的腳本文件,在上例中為scripts子目錄下的main.js文件。用戶自定義的代碼就放在這個(gè)main.js文件中。

      define方法:定義模塊

      define方法用于定義模塊,RequireJS要求每個(gè)模塊放在一個(gè)單獨(dú)的文件里。

      按照是否依賴其他模塊,可以分成兩種情況討論。第一種情況是定義獨(dú)立模塊,即所定義的模塊不依賴其他模塊;第二種情況是定義非獨(dú)立模塊,即所定義的模塊依賴于其他模塊。

      (1)獨(dú)立模塊

      如果被定義的模塊是一個(gè)獨(dú)立模塊,不需要依賴任何其他模塊,可以直接用define方法生成。

      define({
          method1: function() {},
          method2: function() {},
      });

      上面代碼生成了一個(gè)擁有method1、method2兩個(gè)方法的模塊。

      另一種等價(jià)的寫(xiě)法是,把對(duì)象寫(xiě)成一個(gè)函數(shù),該函數(shù)的返回值就是輸出的模塊。

      define(function () {
          return {
              method1: function() {},
              method2: function() {},
          };
      });

      后一種寫(xiě)法的自由度更高一點(diǎn),可以在函數(shù)體內(nèi)寫(xiě)一些模塊初始化代碼。

      值得指出的是,define定義的模塊可以返回任何值,不限于對(duì)象。

      (2)非獨(dú)立模塊

      如果被定義的模塊需要依賴其他模塊,則define方法必須采用下面的格式。

      define(['module1', 'module2'], function(m1, m2) {
         ...
      });

      define方法的第一個(gè)參數(shù)是一個(gè)數(shù)組,它的成員是當(dāng)前模塊所依賴的模塊。比如,['module1', 'module2']表示我們定義的這個(gè)新模塊依賴于module1模塊和module2模塊,只有先加載這兩個(gè)模塊,新模塊才能正常運(yùn)行。一般情況下,module1模塊和module2模塊指的是,當(dāng)前目錄下的module1.js文件和module2.js文件,等同于寫(xiě)成['./module1', './module2']。

      define方法的第二個(gè)參數(shù)是一個(gè)函數(shù),當(dāng)前面數(shù)組的所有成員加載成功后,它將被調(diào)用。它的參數(shù)與數(shù)組的成員一一對(duì)應(yīng),比如function(m1, m2)就表示,這個(gè)函數(shù)的第一個(gè)參數(shù)m1對(duì)應(yīng)module1模塊,第二個(gè)參數(shù)m2對(duì)應(yīng)module2模塊。這個(gè)函數(shù)必須返回一個(gè)對(duì)象,供其他模塊調(diào)用。

      define(['module1', 'module2'], function(m1, m2) {
      
          return {
              method: function() {
                  m1.methodA();
                  m2.methodB();
              }
          };
      
      });

      上面代碼表示新模塊返回一個(gè)對(duì)象,該對(duì)象的method方法就是外部調(diào)用的接口,menthod方法內(nèi)部調(diào)用了m1模塊的methodA方法和m2模塊的methodB方法。

      需要注意的是,回調(diào)函數(shù)必須返回一個(gè)對(duì)象,這個(gè)對(duì)象就是你定義的模塊。

      如果依賴的模塊很多,參數(shù)與模塊一一對(duì)應(yīng)的寫(xiě)法非常麻煩。

      define(
          [       'dep1', 'dep2', 'dep3', 'dep4', 'dep5', 'dep6', 'dep7', 'dep8'],
          function(dep1,   dep2,   dep3,   dep4,   dep5,   dep6,   dep7,   dep8){
              ...
          }
      );

      為了避免像上面代碼那樣繁瑣的寫(xiě)法,RequireJS提供一種更簡(jiǎn)單的寫(xiě)法。

      define(
          function (require) {
              var dep1 = require('dep1'),
                  dep2 = require('dep2'),
                  dep3 = require('dep3'),
                  dep4 = require('dep4'),
                  dep5 = require('dep5'),
                  dep6 = require('dep6'),
                  dep7 = require('dep7'),
                  dep8 = require('dep8');
      
                  ...
          }
      
      });

      下面是一個(gè)define實(shí)際運(yùn)用的例子。

      define(['math', 'graph'], 
          function ( math, graph ) {
              return {
                  plot: function(x, y){
                      return graph.drawPie(math.randomGrid(x,y));
                  }
              }
          };
      );

      上面代碼定義的模塊依賴math和graph兩個(gè)庫(kù),然后返回一個(gè)具有plot接口的對(duì)象。

      另一個(gè)實(shí)際的例子是,通過(guò)判斷瀏覽器是否為IE,而選擇加載zepto或jQuery。

      define(('__proto__' in {} ? ['zepto'] : ['jquery']), function($) {
          return $;
      });

      上面代碼定義了一個(gè)中間模塊,該模塊先判斷瀏覽器是否支持proto屬性(除了IE,其他瀏覽器都支持),如果返回true,就加載zepto庫(kù),否則加載jQuery庫(kù)。

      require方法:調(diào)用模塊

      require方法用于調(diào)用模塊。它的參數(shù)與define方法類(lèi)似。

      require(['foo', 'bar'], function ( foo, bar ) {
              foo.doSomething();
      });

      上面方法表示加載foo和bar兩個(gè)模塊,當(dāng)這兩個(gè)模塊都加載成功后,執(zhí)行一個(gè)回調(diào)函數(shù)。該回調(diào)函數(shù)就用來(lái)完成具體的任務(wù)。

      require方法的第一個(gè)參數(shù),是一個(gè)表示依賴關(guān)系的數(shù)組。這個(gè)數(shù)組可以寫(xiě)得很靈活,請(qǐng)看下面的例子。

      require( [ window.JSON ? undefined : 'util/json2' ], function ( JSON ) {
        JSON = JSON || window.JSON;
      
        console.log( JSON.parse( '{ "JSON" : "HERE" }' ) );
      });

      上面代碼加載JSON模塊時(shí),首先判斷瀏覽器是否原生支持JSON對(duì)象。如果是的,則將undefined傳入回調(diào)函數(shù),否則加載util目錄下的json2模塊。

      require方法也可以用在define方法內(nèi)部。

      define(function (require) {
         var otherModule = require('otherModule');
      });

      下面的例子顯示了如何動(dòng)態(tài)加載模塊。

      define(function ( require ) {
          var isReady = false, foobar;
       
          require(['foo', 'bar'], function (foo, bar) {
              isReady = true;
              foobar = foo() + bar();
          });
       
          return {
              isReady: isReady,
              foobar: foobar
          };
      });

      上面代碼所定義的模塊,內(nèi)部加載了foo和bar兩個(gè)模塊,在沒(méi)有加載完成前,isReady屬性值為false,加載完成后就變成了true。因此,可以根據(jù)isReady屬性的值,決定下一步的動(dòng)作。

      下面的例子是模塊的輸出結(jié)果是一個(gè)promise對(duì)象。

      define(['lib/Deferred'], function( Deferred ){
          var defer = new Deferred(); 
          require(['lib/templates/?index.html','lib/data/?stats'],
              function( template, data ){
                  defer.resolve({ template: template, data:data });
              }
          );
          return defer.promise();
      });

      上面代碼的define方法返回一個(gè)promise對(duì)象,可以在該對(duì)象的then方法,指定下一步的動(dòng)作。

      如果服務(wù)器端采用JSONP模式,則可以直接在require中調(diào)用,方法是指定JSONP的callback參數(shù)為define。

      require( [ 
          "http:///foo?callback=define"
      ], function (data) {
          console.log(data);
      });

      require方法允許添加第三個(gè)參數(shù),即錯(cuò)誤處理的回調(diào)函數(shù)。

      require(
          [ "backbone" ], 
          function ( Backbone ) {
              return Backbone.View.extend({ /* ... */ });
          }, 
          function (err) {
              // ...
          }
      );

      require方法的第三個(gè)參數(shù),即處理錯(cuò)誤的回調(diào)函數(shù),接受一個(gè)error對(duì)象作為參數(shù)。

      require對(duì)象還允許指定一個(gè)全局性的Error事件的監(jiān)聽(tīng)函數(shù)。所有沒(méi)有被上面的方法捕獲的錯(cuò)誤,都會(huì)被觸發(fā)這個(gè)監(jiān)聽(tīng)函數(shù)。

      requirejs.onError = function (err) {
          // ...
      };

      AMD模式小結(jié)

      define和require這兩個(gè)定義模塊、調(diào)用模塊的方法,合稱為AMD模式。它的模塊定義的方法非常清晰,不會(huì)污染全局環(huán)境,能夠清楚地顯示依賴關(guān)系。

      AMD模式可以用于瀏覽器環(huán)境,并且允許非同步加載模塊,也可以根據(jù)需要?jiǎng)討B(tài)加載模塊。

      配置require.js:config方法

      require方法本身也是一個(gè)對(duì)象,它帶有一個(gè)config方法,用來(lái)配置require.js運(yùn)行參數(shù)。config方法接受一個(gè)對(duì)象作為參數(shù)。

      require.config({
          paths: {
              jquery: [
                  '//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js',
                  'lib/jquery'
              ]
          }
      });

      config方法的參數(shù)對(duì)象有以下主要成員:

      (1)paths

      paths參數(shù)指定各個(gè)模塊的位置。這個(gè)位置可以是同一個(gè)服務(wù)器上的相對(duì)位置,也可以是外部網(wǎng)址。可以為每個(gè)模塊定義多個(gè)位置,如果第一個(gè)位置加載失敗,則加載第二個(gè)位置,上面的示例就表示如果CDN加載失敗,則加載服務(wù)器上的備用腳本。需要注意的是,指定本地文件路徑時(shí),可以省略文件最后的js后綴名。

      require(["jquery"], function($) {
          // ...
      });

      上面代碼加載jquery模塊,因?yàn)閖query的路徑已經(jīng)在paths參數(shù)中定義了,所以就會(huì)到事先設(shè)定的位置下載。

      (2)baseUrl

      baseUrl參數(shù)指定本地模塊位置的基準(zhǔn)目錄,即本地模塊的路徑是相對(duì)于哪個(gè)目錄的。該屬性通常由require.js加載時(shí)的data-main屬性指定。

      (3)shim

      有些庫(kù)不是AMD兼容的,這時(shí)就需要指定shim屬性的值。shim可以理解成“墊片”,用來(lái)幫助require.js加載非AMD規(guī)范的庫(kù)。

      require.config({
          paths: {
              "backbone": "vendor/backbone",
              "underscore": "vendor/underscore"
          },
          shim: {
              "backbone": {
                  deps: [ "underscore" ],
                  exports: "Backbone"
              },
              "underscore": {
                  exports: "_"
              }
          }
      });

      上面代碼中的backbone和underscore就是非AMD規(guī)范的庫(kù)。shim指定它們的依賴關(guān)系(backbone依賴于underscore),以及輸出符號(hào)(backbone為“Backbone”,underscore為“_”)。

      插件

      RequireJS允許使用插件,加載各種格式的數(shù)據(jù)。完整的插件清單可以查看官方網(wǎng)站

      下面是插入文本數(shù)據(jù)所使用的text插件的例子。

      define([
          'backbone',
          'text!templates.html'
      ], function( Backbone, template ){
         // ...
      });

      上面代碼加載的第一個(gè)模塊是backbone,第二個(gè)模塊則是一個(gè)文本,用'text!'表示。該文本作為字符串,存放在回調(diào)函數(shù)的template變量中。

      優(yōu)化器r.js

      RequireJS提供一個(gè)基于node.js的命令行工具r.js,用來(lái)壓縮多個(gè)js文件。它的主要作用是將多個(gè)模塊文件壓縮合并成一個(gè)腳本文件,以減少網(wǎng)頁(yè)的HTTP請(qǐng)求數(shù)。

      第一步是安裝r.js(假設(shè)已經(jīng)安裝了node.js)。

      npm install -g requirejs

      然后,使用的時(shí)候,直接在命令行鍵入以下格式的命令。

      node r.js -o <arguments>

      <argument>表示命令運(yùn)行時(shí),所需要的一系列參數(shù),比如像下面這樣:

      node r.js -o baseUrl=. name=main out=main-built.js

      除了直接在命令行提供參數(shù)設(shè)置,也可以將參數(shù)寫(xiě)入一個(gè)文件,假定文件名為build.js。

      ({
          baseUrl: ".",
          name: "main",
          out: "main-built.js"
      })

      然后,在命令行下用r.js運(yùn)行這個(gè)參數(shù)文件,就OK了,不需要其他步驟了。

      node r.js -o build.js

      下面是一個(gè)參數(shù)文件的范例,假定位置就在根目錄下,文件名為build.js。

      ({
          appDir: './',
          baseUrl: './js',
          dir: './dist',
          modules: [
              {
                  name: 'main'
              }
          ],
          fileExclusionRegExp: /^(r|build)\.js$/,
          optimizeCss: 'standard',
          removeCombined: true,
          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'
              }
          }
      })

      上面代碼將多個(gè)模塊壓縮合并成一個(gè)main.js。

      參數(shù)文件的主要成員解釋如下:

      • appDir:項(xiàng)目目錄,相對(duì)于參數(shù)文件的位置。

      • baseUrl:js文件的位置。

      • dir:輸出目錄。

      • modules:一個(gè)包含對(duì)象的數(shù)組,每個(gè)對(duì)象就是一個(gè)要被優(yōu)化的模塊。

      • fileExclusionRegExp:凡是匹配這個(gè)正則表達(dá)式的文件名,都不會(huì)被拷貝到輸出目錄。

      • optimizeCss: 自動(dòng)壓縮CSS文件,可取的值包括“none”, “standard”, “standard.keepLines”, “standard.keepComments”, “standard.keepComments.keepLines”。

      • removeCombined:如果為true,合并后的原文件將不保留在輸出目錄中。

      • paths:各個(gè)模塊的相對(duì)路徑,可以省略js后綴名。

      • shim:配置依賴性關(guān)系。如果某一個(gè)模塊不是AMD模式定義的,就可以用shim屬性指定模塊的依賴性關(guān)系和輸出值。

      • generateSourceMaps:是否要生成source map文件。

      更詳細(xì)的解釋可以參考官方文檔

      運(yùn)行優(yōu)化命令后,可以前往dist目錄查看優(yōu)化后的文件。

      下面是另一個(gè)build.js的例子。

      ({
          mainConfigFile : "js/main.js",
          baseUrl: "js",
          removeCombined: true,
          findNestedDependencies: true,
          dir: "dist",
          modules: [
              {
                  name: "main",
                  exclude: [
                      "infrastructure"
                  ]
              },
              {
                  name: "infrastructure"
              }
          ]
      })

      上面代碼將模塊文件壓縮合并成兩個(gè)文件,第一個(gè)是main.js(指定排除infrastructure.js),第二個(gè)則是infrastructure.js。

      參考鏈接

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類(lèi)似文章 更多