【问题标题】:require.js order plugin issue with traditional files传统文件的require.js订单插件问题
【发布时间】:2012-05-11 11:59:56
【问题描述】:

我有以下使用 require.js 的代码。

utilities.js:

define(["thirdparty-script-A.js"], function(){ ... });

application.js:

define(["utilities", "order!thirdparty-script-A.js", "order!thirdparty-script-B.js"], function(){ ... });

thirdparty-script-B.js 依赖于thirdparty-script-A.js,如果thirdparty-script-A.js 尚未完成加载(执行),将无法正确加载。

总而言之,依赖结构如下所示:

  utilities +---> thirdparty-script-A.js <---+ thirdparty-script-B.js

        ^                   ^                          ^
        |                   |                          |
        |                   +                          |
        |                                              |
        +------------+ application.js +----------------+

查看firebug,我看到获取顺序是:

  1. 实用程序
  2. 第三方脚本-A.js
  3. 应用
  4. 第三方脚本-B.js

从使用 console.log() 调试(从理论上),加载(执行)顺序是:

  1. 第三方脚本-A.js
  2. 实用程序
  3. 第三方脚本-B.js
  4. 应用

问题来了。 在大多数情况下,上述方法在 firefox、chrome 和 IE9 中运行良好。但是,存在由于 thirdparty-script-A.js 尚未完成加载而导致第三方脚本 B.js 无法加载的情况。事实上,console.logs 显示thirdparty-script-B.js 执行FIRST,然后是thirdparty-A.js,实用程序,最后是应用程序。到底是怎么回事?到目前为止,我只能在IE9中重现这个问题。

这很奇怪,因为在 application.js 中,我使用 order 插件来保证两个第三方脚本加载的顺序。然而脚本却乱序执行。

经过进一步调查,我注意到只有在thirdparty-script-A.js 的获取时间比thirdparty-script-B.js 长时才会出现该问题。这让我猜测顺序!插件不适用于define()。理论上,thirdparty-script-B.js 应该等待执行,即使 thirdparty-script-A.js 需要 20 秒来获取和加载。就是这样安排的!行为,不是吗?

另一种理论是,如果任何文件按顺序排列,它将无法正常工作!在链上的另一个模块中是必需的(utilities.js 中的thirdparty-script-A.js)。

我确实有一个解决方法。那就是将 application.js 包装在 require() 中,并让它首先加载所有传统脚本。

require(["order!thirdparty-script-A.js", "order!thirdparty-script-B.js", "application"], function(app){ //app.init }

然而,对于一个超过 60 个脚本的应用程序,需求列表可能会变得又长又乱......

谁能启发我为什么要定义()和订购!表现得像他们一样吗?

非常感谢!

是的,第三方脚本-A 和 B 被缓存了。 =)

【问题讨论】:

    标签: javascript internet-explorer-9 requirejs


    【解决方案1】:

    诀窍是将所有内容包装在模块中。我通常对依赖 jQuery 的第三方插件进行这种“重新打包”。这样,您可以确定在加载插件时加载了 jQuery(并且 $ 存在)。这种方式不需要订单插件。

    通过“重新打包”,您只需将插件代码及其依赖项包装在 define() 调用中,然后正常加载。

    在应用中:

    define(['utilities','scriptA','scriptB'],function(){
        //application code
    });
    

    在实用程序中:

    define(['scriptA'],function(){
        //utilities code
    });
    

    在脚本B中

    define(['scriptA'],function(){
        //scriptB code
    });
    

    在脚本A中

    define(function(){
        //scriptA code
    });
    

    所以顺序是:

    Loading |      Application       A
            |   Utilities, Script B  |
            V       Script A         | Execution
             \----->----->----->----/ 
    

    ScriptA 可能已经被加载并更早地执行,因为应用程序依赖它。但为了安全起见,你应该这样做。这样,您就可以确定依赖项已正确加载。

    【讨论】:

    • 感谢您的快速回复,但是快速重新打包不会导致维护第三方脚本的困难吗?即每次我想升级脚本时,我都需要使用define()来修补它. =( 我想包装器可以是另一个文件,例如 scriptA-wrapper.js 将是 define(["scriptA.js"], function(){ ... });
    • @KenHirakawa 我以前确实遇到过这个问题,这是确保在集成第三方脚本的依赖项之前满足它们的唯一方法。是的,每次这些插件的新版本到来时,你都会打补丁。你可以做的是制作一个包装程序(类似于 Require 的优化器),它采用插件并创建它的包装版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-31
    • 2022-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多