• RequireJS 笔记


    概述

    RequireJS 是一个工具库,能在网页中进行模块化编程,从而提高代码的性能和可维护性。它的模块管理遵守 AMD 规范。类似的库还有 sea.js 国人开发的一个库,遵守 CMD 规范。

    个人推荐使用 RequireJS 库,从功能上说,两者是差不多的,但 RequireJS 有完善的文档和很好的打包工具可用,相比 sea.js 强多了,在这里吐槽下,感觉之前被 sea.js 坑了不少。

    使用

    加载 javascript 文件

    RequireJS 以一个相对于 baseUrl 的地址来加载所有的代码。 页面顶层 <script> 标签含有一个特殊的属性 data-main 使用它来启动脚本加载过程,而 baseUrl 一般设置到与该属性相一致的目录。

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

    baseUrl 亦可通过 RequireJS config 手动设置。如果没有显式指定 config 及 data-main ,则默认的 baseUrl 为包含 RequireJS 的那个 HTML 页面的所属目录。

    若符合下述规则之一,则可避开 baseUrl + paths 配置

    • 以 ".js" 结束
    • 以 "/" 开始
    • 包含 URL 协议, 如 "http:" or "https:"

    一般来说,最好还是使用 baseUrlpaths 去设置。它会给你带来额外的灵活性,如便于脚本的重命名、重定位等。同时,为了避免凌乱的配置,最好不要使用多级嵌套的目录层次来组织代码。

    模块的定义

    1.Simple Name/Value Pairs

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

    2.Definition Functions

    define(function () {
        // ...
    
        return {
            color: "black",
            size: "unisize"
        }
    });
    

    3.Definition Functions with Dependencies

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

    依赖关系会以参数的形式注入到函数上,参数列表与依赖名称列表一一对应。

    4.Define a Module as a Function

    define(["my/cart", "my/inventory"],
        function(cart, inventory) {
            //return a function.
            //It gets or sets the window title.
            return function(title) {
                return title ? (window.title = title) :
                       inventory.storeName + ' ' + cart.name;
            }
        }
    );
    

    5.Define a Module with Simplified CommonJS Wrapper

    define(function(require, exports, module) {
            var a = require('a'),
                b = require('b');
    
            //Return the module value
            return function () {};
        }
    );
    

    利用 Function.prototype.toString() 实现,但在一些设备如 PS3 及一些老的 Opera 手机浏览器中不起作用。

    6.Define a Module with a Name

    define("foo/title",
        ["my/cart", "my/inventory"],
        function(cart, inventory) {
            //...
       }
    );
    

    可看到一些 define() 中包含了一个模块名称作为首个参数,这些常由打包工具生成。你也可以自己显式指定模块名称,但这使模块更不具备移植性——就是说若你将文件移动到其他目录下,你就得重命名。

    Loader Plugins

    有关 Loader Plugins 可跳转阅读 http://requirejs.org/docs/api.html#plugins 有关 requirejs 插件的编写可跳阅 http://requirejs.org/docs/plugins.html#api

    CommonJS Compatibility

    //BAD
    var mod = require(someCondition ? 'a' : 'b');
    
    //BAD
    if (someCondition) {
        var a = require('a');
    } else {
        var b = require('b');
    

    以上的写法在 RequireJS 中是错误的用法,这样做的话, a 和 b 这两模块都会加载到页面中,这里可查看下文给出的列子。详细可点击阅读 CommonJS Compatibility
    这种业务场景的解决方案 callback-require

    机制

    RequireJS 使用 head.appendChild() 将每一个依赖加载为一个 script 标签。
    RequireJS 等待所有的依赖加载完毕,加载是异步的,计算出模块定义函数正确调用顺序,然后依次调用它们。

    打包

    RequireJS 提供一个基于 node.js 的命令行工具 r.js ,用来压缩多个 js 文件。它的主要作用是将多个模块文件压缩合并成一个脚本文件,以减少网页的HTTP请求数。例:

    node r.js -o baseUrl=. name=main out=main-built.js
    

    除了直接在命令行提供参数设置,也可以将参数写入一个文件,假定文件名为 build.js

    node r.js -o build.js
    

    有关更多的配置项可查看 example.build.js 和一个打包示例 requirejs/example-multipage

    进一步优化,使用 r.js 优化后的代码可以使用 almond 来加载。

    RequireJS 用法示例

    例子中有对上文内容的一些补充,建议详细阅读代码。大家可点击 例子 打开看看,留意控制台的输出,注意这里为了演示就没有对 js 进行打包。

    相关阅读

    作者:avilang
    个人博客:avilang.me
    GitHub:avilang

    转载文章,请标明出处。
  • 相关阅读:
    linux-kernel邮件列表订阅出错,提示命令不能识别---解决方案
    MD5(单向散列算法)原理分析
    win32汇编跳转指令用法
    (转载)c/c++优先级列表
    linux man手册各个章节的意义
    如何解决dpkg: error processing install-info
    python魔法函数(常见)
    redis 哈希封装
    数据库去重
    抖音破解字体加密
  • 原文地址:https://www.cnblogs.com/avilang/p/6741804.html
Copyright © 2020-2023  润新知