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则表示在当前路径回退两个文件层。

相关文章
相关标签/搜索