require模块开发(一)

1.require下载和加载

1.1 下载

工欲善其事必先利其器,先下载require.js下载地址, 然后添加 require.js 到 scripts 目录

1.2 加载

然后加载require

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

data-main属性的作用是,指定网页程序的主模块

注意,这里写的是app而不是app.js。RequireJS默认假定所有的依赖资源都是js脚本,因此无需在module ID上再加".js"后缀,RequireJS在进行module ID到path的解析时会自动补上后缀.

1.3 baseUrl、path配置

在上面的app.js里的模块代码有

require(['jquery', 'underscore', 'backbone'], function ($, _, Backbone){
    // some code here
  });

默认情况'jquery', 'underscore', 'backbone'是和app.js在同一目录下。如果这些文件不和app.js在同一目录怎么办,比如js/lib目录下。

两种办法:

第一种办法:改变paths

  require.config({
    paths: {
      "jquery": "lib/jquery.min",
      "underscore": "lib/underscore.min",
      "backbone": "lib/backbone.min"
    }
  });

第二种办法:改变baseurl

baseUrl :所有模块的查找根路径。如未显式设置baseUrl,则默认值是加载require.js的HTML所处的位置。如果用了data-main属性,则该路径就变成baseUrl。

  require.config({
    baseUrl: "js/lib",
    paths: {
      "jquery": "jquery.min",
      "underscore": "underscore.min",
      "backbone": "backbone.min"
    }
  });

1.4加载非规范的模块

有些模块并不是规范的AMD,如果已存在的jquery等控件。这样的文件如果 加载

   require.config({
    shim: {

      'jquery':{
        exports: $'
      },
      'backbone': {
        deps: ['underscore', 'jquery'],
        exports: 'Backbone'
      }
    }
  });

 2.定义模块

一个磁盘文件应该只定义 1 个模块。多个模块可以使用内置优化工具将其组织打包。

2.1简单的值对

define({
    color: "black",
    size: "unisize"
});

2.2函数式定义

如果一个模块没有任何依赖,但需要一个做setup工作的函数,则在define()中定义该函数,并将其传给define():

define(function () {
    //Do setup work here

    return {
        color: "black",
        size: "unisize"
    }
});

2.3存在依赖的函数式定义

第一个参数是依赖的名称数组;第二个参数是函数,在模块的所有依赖加载完毕后,该函数会被调用来定义该模块,因此该模块应该返回一个定义了本模块的object。

define(["./cart", "./inventory"], function(cart, inventory) {
        //return an object to define the "my/shirt" module.
        return {
            color: "blue",
            size: "large",
            addToCart: function() {
                inventory.decrement(this);
                cart.add(this);
            }
        }
    }
);

2.4定义一个命名模块 

    //Explicitly defines the "foo/title" module:
    define("foo/title",
        ["my/cart", "my/inventory"],
        function(cart, inventory) {
            //Define foo/title object in here.
       }
    );

显式指定模块名称,但这使模块更不具备移植性

 2.5循环依赖

如果你定义了一个循环依赖(a依赖b,b同时依赖a),则在这种情形下当b的模块函数被调用的时候,它会得到一个undefined的a.解决办法

//Inside b.js:
define(function(require, exports, module) {
    //If "a" has used exports, then we have a real
    //object reference here. However, we cannot use
    //any of a's properties until after b returns a value.
    var a = require("a");

    exports.foo = function () {
        return a.bar();
    };
});

 2.6 两类模块需要使用不同版本的"foo"

该手段对于某些大型项目很重要:如有两类模块需要使用不同版本的"foo",但它们之间仍需要一定的协同

map示例:

requirejs.config({
    map: {
        'some/newmodule': {
            'foo': 'foo1.2'
        },
        'some/oldmodule': {
            'foo': 'foo1.0'
        }
    }
});

如果各模块在磁盘上分布如下:

  • foo1.0.js
  • foo1.2.js
  • some/
    • newmodule.js
    • oldmodule.js

当“some/newmodule”调用了“require('foo')”,它将获取到foo1.2.js文件;而当“some/oldmod

requirejs.config({
    config: {
        'bar': {
            size: 'large'
        },
        'baz': {
            color: 'blue'
        }
    }
});

//bar.js, which uses simplified CJS wrapping:
//http://requirejs.org/docs/whyamd.html#sugar
define(function (require, exports, module) {
    //Will be the value 'large'
    var size = module.config().size;
});

//baz.js which uses a dependency array,
//it asks for the special module ID, 'module':
//https://github.com/jrburke/requirejs/wiki/Differences-between-the-simplified-CommonJS-wrapper-and-standard-AMD-define#wiki-magic
define(['module'], function (module) {
    //Will be the value 'blue'
    var color = module.config().color;
});

若要将config传给包,将目标设置为包的主模块而不是包ID:

ule”调用“`require('foo')”时它将获取到foo1.0.js。

2.7配置信息

config:常常需要将配置信息传给一个模块,并调用module.config()。

requirejs.config({
    //Pass an API key for use in the pixie package's
    //main module.
    config: {
        'pixie/index': {
            apiKey: 'XJKDLNS'
        }
    },
    //Set up config for the "pixie" package, whose main
    //module is the index.js file in the pixie folder.
    packages: [
        {
            name: 'pixie',
            main: 'index'
        }
    ]
});

一个常见的应用场景是先用库的一个CDN版本,如果其加载出错,则切换到本地版本:

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min'
    }
});

//Later
require(['jquery'], function ($) {
    //Do something with $ here
}, function (err) {
    //The errback, error callback
    //The error has a list of modules that failed
    var failedId = err.requireModules && err.requireModules[0];
    if (failedId === 'jquery') {
        //undef is function only on the global requirejs object.
        //Use it to clear internal knowledge of jQuery. Any modules
        //that were dependent on jQuery and in the middle of loading
        //will not be loaded yet, they will wait until a valid jQuery
        //does load.
        requirejs.undef(failedId);

        //Set the path to jQuery to local path
        requirejs.config({
            paths: {
                jquery: 'local/jquery'
            }
        });

        //Try again. Note that the above require callback
        //with the "Do something with $ here" comment will
        //be called if this new attempt to load jQuery succeeds.
        require(['jquery'], function () {});
    } else {
        //Some other error. Maybe show message to the user.
    }
});

注意: errback仅适用于回调风格的require调用,而不是define()调用。define()仅用于声明模块。

更简单办法

requirejs.config({
    //To get timely, correct error triggers in IE, force a define/shim exports check.
    enforceDefine: true,
    paths: {
        jquery: [
            'http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min',
            //If the CDN location fails, load from this location
            'lib/jquery'
        ]
    }
});

//Later
require(['jquery'], function ($) {
});

全局 requirejs.onError

requirejs.onError = function (err) {
    console.log(err.requireType);
    if (err.requireType === 'timeout') {
        console.log('modules: ' + err.requireModules);
    }

    throw err;
};

页面加载事件及DOM Ready

domReady模块实现了一个跨浏览器的方法来判定何时DOM已经ready。下载并在你的项目中如此用它:

  require(['domready!'], function (doc){
    // called once the DOM is ready
  });
原文地址:https://www.cnblogs.com/myzy/p/6273098.html