requirejs:模塊加載(require)及定義(define)時的路徑小結

  最近在看公司項目的時候,對requireJS的define的路徑有必定的困惑,經過查閱資料作一下總結:html

  requirejs中不管是經過define來定義模塊,仍是經過require來加載模塊,模塊依賴聲明都是很重要的一步。假設咱們的目錄結構以下:jquery

demo.html 
js/main.js 
js/lib.js 
js/util.js 
js/common/lib.js 
js/common/jqury/lib.js 
common/lib.js
  • baseUrl

  在requirejs的模塊路徑解析裏,  baseUrl 是很是基礎的概念,離開了它,基本就玩不轉了,因此這裏簡單介紹一下。簡單的說,  baseUrl 指定了一個目錄,而後requirejs基於這個目錄來尋找依賴的模塊。app

  在demo.html里加載requirejs,同時在requirejs所在的script上聲明  data-main 屬性,那麼,requirejs加載下來後,它會作兩件事件:requirejs

  1. 加載js/main.js
  2. 將baseUrl設置爲data-main指定的文件所在的路徑,這裏是 js/
<script src="js/require.js" data-main="js/main.js"></script>

  那麼,下面依賴的lib模塊的實際路徑爲  js/lib.jsui

  main.jsspa

require(['lib'], function(Lib){
    // do sth
});

  除了  data-main 屬性,你也能夠手動配置  baseUrl ,好比下面例子。須要強調的是: 若是沒有經過  data-main 屬性指定  baseUrl ,也沒有經過config的方式顯示聲明  baseUrl ,那麼  baseUrl 默認爲加載requirejs的那個頁面所在的路徑code

  demo.htmlhtm

<script src="js/require.js"></script>
<script src="js/main.js"></script>

  main.jsblog

requirejs.config({
  baseUrl: 'js'
});

require(['lib'], function(Lib){
  // do sth
});
  • baseUrl+path:讓依賴更加簡潔、靈活
  1. 費力氣:每一個加載的模塊前面都有長長的  common/fruits
  2. 難維護:說不定哪一天目錄名就變了(在大型項目中並不算罕見),想象一下目錄結構變動帶來的工做量

  以下:事件

requirejs.config({
  baseUrl: 'js'
});

// 加載一堆水果
require(['common/fruits/apple', 'common/fruits/orange', 'common/fruits/grape', 'common/fruits/pears'], function(Apple, Orange, Grape, Pears){
  // do sth
});

  將其修改成以下內容:

requirejs.config({
  baseUrl: 'js',
  paths: {
    fruits: 'common/fruits'
  }
});

// 加載一堆水果
require(['fruits/apple', 'fruits/orange', 'fruits/grape', 'fruits/pears'], function(Apple, Orange, Grape, Pears){
  // do sth
});

  當項目結構變動時,好處就體現了。假設  common/fruits 某一天忽然變成了  common/third-party/fruits,那很簡單,改下  paths 就能夠了。

  • path:簡單可是實用
  1. apple :沒有在paths規則裏定義,因而爲 baseUrl + apple.js => js/apple.js 
  2. common/fruits :common已經在paths裏定義,因而爲baseUrl + common/fruits + apple.js => js/common/fruits/apple.js 
  3. ../common/apple :common儘管已經在paths裏定義,可是  ../common/apple 並非以common開頭,因而爲 baseUrl + ../common/apple.js => common/apple.js
 1 requirejs.config({
 2   baseUrl: 'js',
 3   paths: {
 4     common: 'common/fruits'
 5   }
 6 });
 7 
 8 // 從左到右,加載的路徑依次爲 js/lib.js、 js/common/jquery/lib.js、common/lib.js
 9 require(['apple', 'common/apple', '../common/apple'], function(){
10   // do something
11 });
  • ./medole:疑惑的相對路徑

  一、demo1

  js/main.js

requirejs.config({
  baseUrl: 'js/common'
});
// 實際加載的路徑都是是 js/common/lib.js
require(['./lib', 'lib'], function(Lib){
  Lib.say('hello');
});

  二、demo2

  簡單改下上面的例子,能夠看到:經過  define 定義模塊A時,模塊A依賴的模塊B,若是是  ./module 形式,則基於模塊A所在目錄解析模塊B的路徑。

  js/main.js

requirejs.config({
  baseUrl: 'js'
});
// 依賴lib.js,實際加載的路徑是 js/common/lib.js,而lib模塊又依賴於util模塊('./util'),解析後的實際路徑爲 js/common/util.js
require(['common/lib'], function(Lib){
  Lib.say('hello');
});

  js/lib.js

// 依賴util模塊
define(['./util'], function(Util){
    return {
        say: function(msg){
            Util.say(msg);
        }
    };
});

  三、demo 3

  demo2實際上會有特例,好比下面,lib模塊依賴的util模塊,最終解析出來的路徑是 js/util.js

  main.js

requirejs.config({
  baseUrl: 'js',
  paths: {
    lib: 'common/lib'
  }
});

// 實際加載的路徑是 js/common/lib.js
require(['lib'], function(Lib){
  Lib.say('hello');
});

  lib.js

// util模塊解析後的路徑爲 js/util.js
define(['./util'], function(Lib){
    return {
        say: function(msg){
            Lib.say(msg);
        }
    };
});

  四、demo 4

  ./module 路徑解析就會按照  baseUrl +  moduleName 的方式,但稍微修改下main.js,發現結果就不同了。此時,util模塊對應的路徑爲  js/common/util.js

  main.js

requirejs.config({
  baseUrl: 'js',
  paths: {
    common: 'common'
  }
});
// 實際加載的路徑是 js/common/lib.js
require(['common/lib'], function(Lib){
  Lib.say('hello');
});

  lib.js

define(['./util'], function(Lib){
    return {
        say: function(msg){
            Lib.say(msg);
        }
    };
});

  requirejs中的路徑解析總體上不復雜,但  ./module 這種形式的路徑解析,總之,就是不要讓requirejs感到困惑,讓其尋找baseUrl。

  另外,若是../module則表示在當前路徑回退兩個文件層。

相關文章
相關標籤/搜索