【问题标题】:requirejs: What is the difference between these methods of establishing module requirements?requirejs:这些建立模块需求的方法有什么区别?
【发布时间】:2014-03-14 04:56:27
【问题描述】:

以下两种建立依赖关系的方法有什么区别,它们似乎达到了完全相同的结果。对我来说,使用 #1 管理依赖项更容易:

//#1
define(function (require) {
    var $ = require('jquery');
    //$ is available here
});
//#2
define(['jquery'],function ($) {
    //$ is available here
});

使用#1 有什么缺点吗?我在构建将其依赖项包含在一个文件中的模块时遇到了一些困难。使用#1 有什么关系吗?

这是这个问题: requirejs: Build settings for a common.js module along with a main.js module where the result will be only two .js files served

【问题讨论】:

    标签: javascript requirejs amd


    【解决方案1】:

    这两种配方达到了相同的效果。在内部,RequireJS 将第一个公式转换为:

    define(['jquery'], function (require) {
        var $ = require('jquery');
        //$ is available here
    });
    

    它使用单个字符串参数扫描函数以查找对 require 的调用,收集所有参数并将它们添加到传递给 define 的依赖项列表中。因此,由于两个原因,它比第二种公式的计算成本要高一些。首先,RequireJS 必须使用正则表达式来扫描函数并找到对require 的调用。其次,当你像这样加载多个模块时,require 必须被多次调用。比较一个依赖于其他4个模块并使用var x = require('x')加载它们的模块,转换后:

    define(['a', 'b', 'c', 'd'], function (require) {
        var a = require('a');
        var b = require('b');
        var c = require('c');
        var d = require('d');
    
        // Actual work.
    });
    

    同样的模块是这样写的:

    define(['a', 'b', 'c', 'd'], function (a, b, c, d) {
        // Actual work.
    });
    

    第一个模块需要调用require 四次才能进入实际工作部分。我不会因为性能差异而失眠,但它确实存在。

    Jeremy 指出了第一个公式的局限性,但 elsewhere 在文档中,James Burke(RequireJS 的作者)对这个可能的问题给出了更详细的意见:

    并非所有浏览器都会给出可用的 Function.prototype.toString() 结果。截至 2011 年 10 月,PS 3 和更早的 Opera Mobile 浏览器不支持。 这些浏览器更有可能需要针对网络/设备限制优化模块构建,因此只需使用知道如何将这些文件转换为规范化依赖数组形式的优化器进行构建,例如RequireJS 优化器。

    由于不支持这种 toString() 扫描的浏览器数量非常少,对所有模块使用这种糖化形式是安全的,特别是如果您想排列依赖项名称带有将保存其模块值的变量。

    (已添加重点。)

    认为“哦,不!我将必须使用优化器”的人并没有看到全局。有可能toString() 不可用的平台无论如何都需要优化。

    为了解决您的具体问题:

    使用 #1 可以解决这个问题吗?

    使用#1 中的语法糖本身不会使优化器无法优化您的代码。我有一个超过 50 个模块的项目,它混合了两种风格。我不需要做任何特别的事情来使r.js 工作。

    【讨论】:

    • 非常翔实,感谢您的详细比较。这一点现在很清楚,似乎因为我使用的是 r.js,所以这在我的构建中应该不是问题。
    【解决方案2】:

    文档位于:

    http://requirejs.org/docs/api.html#funcmodule

    解释了第一种格式的最大问题——它依赖于Function::prototype::toString,这不是 100% 可靠的。

    编辑

    来自文档:

    这个包装器依赖于 Function.prototype.toString() 来提供函数内容的有用字符串值。这不适用于某些设备,例如 PS3 和一些较旧的 Opera 移动浏览器。使用优化器以数组格式提取依赖项,以便在这些设备上使用。

    【讨论】:

    • 我认为与您的链接指向的 funcmodule 相关的问题或提及的负面含义没有任何关系。我是不是错过了什么。你能详细说明一下吗?
    • 啊。好眼力。您是否有机会查看我问题底部的其他问题链接?你似乎很了解requirejs。这让我发疯;)。奇怪的是作者或 requirejs 会在他的示例中使用该方法,因为它有问题。
    • 说实话,我只玩过一次 requireJS 构建的东西,我花了几天的时间才弄清楚细节。唉,那个工作中的特定项目被放弃了,我们的 repo 经历了一个代码 rebase,所以——如果不付出很大的努力,我就无法得到那些东西。对不起。
    • 我想我只是浪费了过去几天试图让这个工作。理论上听起来很糟糕。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-11
    • 2018-04-29
    • 2011-12-24
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多