RequireJS

Table of Contents

1 RequireJS简介

RequireJS is a JavaScript file and module loader.

RequireJS遵循AMD(Asynchronous Module Definition)规范。

注:ECMAScript 6已经有了模块系统,但需要很长一段时间才能真正用于产品中。

1.1 为什么需要RequireJS

为什么需要RequireJS?有两个主要原因:
(1)实现js文件的异步加载,避免网页失去响应;
(2)管理模块之间的依赖性,便于代码的编写和维护。

参考:
http://www.ruanyifeng.com/blog/2012/11/require_js.html
https://www.sitepoint.com/understanding-requirejs-for-effective-javascript-module-loading/

2 安装配置RequireJS

RequireJS可以从其官网上下载,假设下载后你把它放到了你工程的scripts目录下面。
工程目录结构看起来像这样:

project-directory/
  index.html
  scripts/
    main.js
    require.js
    lib/
      jquery.min.js
      underscore.min.js
      myModuleA.js

要使用RequireJS,直接在html文件中加入 <script data-main="scripts/main" src="scripts/require.js"></script> 即可:

<!DOCTYPE html>
<html>
    <head>
        <title>My Sample Project</title>
        <!-- data-main attribute tells require.js to load
             scripts/main.js after require.js loads. -->
        <script data-main="scripts/main" src="scripts/require.js"></script>
    </head>
    <body>
        <h1>My Sample Project</h1>
    </body>
</html>

说明1:上面代码中,浏览器会加载脚本scripts/require.js,而“data-main”是一个用户自定义的属性,它并不是script标签下的标准属性,在脚本scripts/require.js中会分析属性“data-main”所关联的脚本(即scripts/main.js,RequireJS中默认后缀为js可以省略),并加载它。我们可以在RequireJS的源码中找到相关的处理代码:

// require.js 2.1.6 的部分源码
dataMain = script.getAttribute('data-main');
......
// Put the data-main script in the files to load.
cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript];

说明2:data-main关联的scripts/main.js称为主模块,主模块中可以加载其它依赖的模块。RequireJS要求主模块和其它模块按一定的格式来书写。

3 RequireJS基本用法

require.js这个文件中定义了三个变量:requirejs,require,define,其中requirejs和require是一样的,使用require更简短。
require是用来加载依赖模块的,加载完后执行回调函数。而define则是用来定义一个模块的。

3.1 require函数(主模块的编写)

require()函数接受两个参数。第一个参数是数组,表示想要加载的依赖模块列表;第二个参数是一个回调函数,当前面指定的模块都加载成功后,它将被调用。加载的模块会以参数形式传入该回调函数,从而在回调函数内部就可以使用这些模块。

如:

// file main.js
require.config({
      baseUrl: "scripts/lib",                // 如果不指定baseUrl,就默认在main.js所在目录中查找模块
      paths: {
         "jquery": "jquery.min",
         "underscore": "underscore.min"
      }
});

// require函数接受两个参数,第一个是想要加载的依赖模块列表,第二个是加载模块完成后的回调函数。
require(['jquery', 'underscore', 'myModuleA', 'myModuleB'], function ($, _, myA) {
    // 这里的代码在 jquery 和 underscore 被加载后,会被执行。
    // 这里的代码中可以通过$来引用jquery模块,通过_来引用underscore模块了,通过myA来引用myModuleB模块了。
    // 回调函数只指定了三个参数,说明第4个依赖模块myModuleB没有输出变量,我们不需要引用它。
});

参考:
http://requirejs.org/docs/api.html#data-main

3.2 define函数(其它模块的编写)

用require.js加载的模块,必须按照AMD的规定来书写。即用define()函数来定义。

如定义模块math:

// file math.js
define(function (){
  var add = function (x,y){
    return x+y;
  };
  return {
    add: add
  };
});

可以这样使用前面定义的math模块:

// main.js
require(['math'], function (math){
  alert(math.add(1,1));
});

define还可以接受一个参数(第一个参数)来指定它依赖的模块。如:

define(['myLib'], function(myLib){
  function foo(){
    myLib.doSomething();
  }
  return {
    foo : foo
  };
});

用require函数加载上面模块时,会先加载它的依赖模块myLib。

参考:
http://www.ruanyifeng.com/blog/2012/11/require_js.html
http://requirejs.org/docs/api.html#define

3.3 配置非AMD规范的模块

requirejs默认只能加载AMD规范的模块(即用define()函数定义的模块)。如果要加载非AMD规范的模块,则需要使用 shim 提前配置。

实例:

requirejs.config({

    paths : {
        'jquery' : 'libs/jquery',
        'jquery.colorize' : 'libs/jquery.colorize',
        'jquery.scroll' : 'libs/jquery.scroll',
    },

    shim: {
        'jquery.colorize': ['jquery'],
        'jquery.scroll': ['jquery']
    }
});

完成上面配置后,就可以和使用AMD模块一样使用shim中配置的非AMD模块(如jquery.colorize和jquery.scroll)了。

参考:http://requirejs.org/docs/api.html#config-shim


Author: cig01

Created: <2016-05-29 Sun 00:00>

Last updated: <2016-07-14 Thu 15:18>

Creator: Emacs 25.1.1 (Org mode 9.0.7)