require.js读书笔记 2.usage

USAGE§ 1

Load JavaScript Files 加载javascript文件夹§ 1.1

requireJs用一种新的script加载方法,这种方法和传统<script>标签是完全不同的。它可以运行地更快,并且进行更好地优化,它的主要目的就是为了支持(encourage)模块化(modular)代码的加载。作为其中的一部分,它支持利用模块ID来加载script,而不是script标签里的url属性。

requireJs加载的所有代码地址都是相对于baseUrl的。页面顶层script标签有一个特殊的属性data-main,require.js用它来启动脚本加载页面,而baseUrl通常设置成这个标签所在的文件夹里。data-main attribute是一个特殊的属性,require.js会用这个属性进行加载。下面这个例子会展示了baseUrl的设置:

<!--This sets the baseUrl to the "scripts" directory, and
    loads a script that will have a module ID of ‘main‘-->
<script data-main="scripts/main.js" src="scripts/require.js"></script>

或者,baseUrl可以通过RequireJS config手动(manually)地设置。如果没有明确的(explicit)config设置,或者没有使用data-main属性,那么默认的baseUrl就是包含requireJs的HTML页面所在的目录。

requireJs默认所有依赖(dependence)资源都死scripts,所以写模块ID时不需要.js的后缀。requireJs翻译模块ID的路径时会自动加上.js尾缀的。运用paths config标签,你可以设置一组scripts脚本的位置。相对于<script>标签,这些能让你用更少的字符来加载script。

有时候你想直接饮用一个script,而不是依照(conform)“baseUrl+paths"规则来找它。如果一个模块ID由以下之一的规则,这个ID就不会通过”baseUrl+paths"配置来加载script,而是像普通的script url属性来加载。

  • 以.js结束
  • 以“/”开始
  • url协议(protocol),像 "http:" or "https:".

通常地说,最好通过baseUrl和paths来设置模块ID的路径。这样所,你可以很方便地重命名和重定位脚本(configuring the paths to different locations)。

相似的,为了避免配置凌乱,最好避免多级嵌套(deep folder hierarchies)的方式来加载代码。要么将所有的scripts放在baseUrl的目录中,不然将你的代码分置为目录(library)/第三方目录库(vendor)的结构,可以像以下所示:

  • www/
    • index.html
    • js/
      • app/
        • sub.js
      • lib/
        • jquery.js
        • canvas.js
      • app.js

in index.html:

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

and in app.js:

requirejs.config({
    //设置默认模块ID的路径 js/lib
    baseUrl: ‘js/lib‘,
    //另外,如果模块ID以app开始,
    //它会从js/app目录加载。paths设置时相对于baseUrl的,绝不会包括“.js”的,但是paths设置可以是相对directory的
    paths: {
        app: ‘../app‘
    }
});

开始main app的逻辑。
requirejs([‘jquery‘, ‘canvas‘, ‘app/sub‘], function ($, canvas, sub) { //jQuery, canvas and the app/sub module are all //loaded and can be used here now. });

在这个例子中,第三方库(vendor其实是供应商的意思)如jQuery,并没有将它的版本号显示在文件名中。如果你想跟踪版本号,建议新开一个单独的文件来记录,或者你可以用一些工具,像volo,可以将package.json打上版本信息,但文件名还是jQuery.js。这有助于你的配置最小化,避免为每个版本的库设置paths路径。例如,将"jquery"配置成(configure)“jquery-1,7,2"

理想状态下(ideally),每个加载的脚本都是通过define()来定义的一个模块。然而,有些"浏览器全局变量注入"型传统/遗留(legacy)浏览器可能不能用define()来定义它们的依赖关系。为此(for those),你可以用shim config来解析它们的依赖关系。

如果你不想解析它们的依赖关系,你可能会得到一些加载错误,基于速度的原因(for speed),requireJs会异步( asynchronously)、无序(out of order)地加载脚本。

 

data-main Entry Point§ 1.2

data-main属性是一个特殊属性,require.js在加载脚本的时候会检查(check)它:

<!--当require.js加载的时候,它会忽视script/main.js的其他script标签属性-->
<script data-main="scripts/main" src="scripts/require.js"></script>

你可以在data-main中设置配置选项,然后加载你的第一个应用模块(application module)。注意:require.js的标签加载的模块是异步的async attribute。这意味着,如果你在这个页面加载了其他scripts,则不能保证通过require.js加载的页面可以先于这些脚本加载完毕。

举个例子,以下的构造不能保证foo模块的require.config的路径设置会先于require()foo模块执行:

<script data-main="scripts/main" src="scripts/require.js"></script>
<script src="scripts/other.js"></script>
// contents of main.js:
require.config({
    paths: {
        foo: ‘libs/foo-1.1.3‘
    }
});
// contents of other.js:

//这段代码可能会在main.js 的require.config()之前执行。如果这放生了,require.js会加载‘scripts/foo.js‘额不是‘scripts/libs/foo-1.1.3.js

require([‘foo‘], function(foo) { });

如果你想在HTML页面中调用require(),最好不要用data-main。data-main只用在页面只需要一个入口的时候。如果页面想在行内调用require(),最好如下所示书写代码

<script src="scripts/require.js"></script>
<script>
require([‘scripts/config‘]), function() {
    // Configuration loaded now, safe to do other require calls
    // that depend on that config.
    require([‘foo‘], function(foo) {

    });
});
</script>

Define a Module§ 1.3

A module is different from a traditional script file in that it defines a well-scoped object that avoids polluting the global namespace. It can explicitly list its dependencies and get a handle on those dependencies without needing to refer to global objects, but instead receive the dependencies as arguments to the function that defines the module. Modules in RequireJS are an extension of the Module Pattern, with the benefit of not needing globals to refer to other modules.

The RequireJS syntax for modules allows them to be loaded as fast as possible, even out of order, but evaluated in the correct dependency order, and since global variables are not created, it makes it possible to load multiple versions of a module in a page.

(If you are familiar with or are using CommonJS modules, then please also see CommonJS Notes for information on how the RequireJS module format maps to CommonJS modules).

There should only be one module definition per file on disk. The modules can be grouped into optimized bundles by the optimization tool.

Simple Name/Value Pairs§ 1.3.1

If the module does not have any dependencies, and it is just a collection of name/value pairs, then just pass an object literal to define():

//Inside file my/shirt.js:
define({
    color: "black",
    size: "unisize"
});

Definition Functions§ 1.3.2

If the module does not have dependencies, but needs to use a function to do some setup work, then define itself, pass a function to define():

//my/shirt.js now does setup work
//before returning its module definition.
define(function () {
    //Do setup work here

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

Definition Functions with Dependencies§ 1.3.3

If the module has dependencies, the first argument should be an array of dependency names, and the second argument should be a definition function. The function will be called to define the module once all dependencies have loaded. The function should return an object that defines the module. The dependencies will be passed to the definition function as function arguments, listed in the same order as the order in the dependency array:

//my/shirt.js now has some dependencies, a cart and inventory
//module in the same directory as shirt.js
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);
            }
        }
    }
);

In this example, a my/shirt module is created. It depends on my/cart and my/inventory. On disk, the files are structured like this:

  • my/cart.js
  • my/inventory.js
  • my/shirt.js

The function call above specifies two arguments, "cart" and "inventory". These are the modules represented by the "./cart" and "./inventory" module names.

The function is not called until the my/cart and my/inventory modules have been loaded, and the function receives the modules as the "cart" and "inventory" arguments.

Modules that define globals are explicitly discouraged, so that multiple versions of a module can exist in a page at a time (see Advanced Usage). Also, the order of the function arguments should match the order of the dependencies.

The return object from the function call defines the "my/shirt" module. By defining modules in this way, "my/shirt" does not exist as a global object.

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。