RequireJS 订单插件和 Dojo 1.7.1

Posted

技术标签:

【中文标题】RequireJS 订单插件和 Dojo 1.7.1【英文标题】:The RequireJS order plugin and Dojo 1.7.1 【发布时间】:2012-01-11 09:20:25 【问题描述】:

我正在使用 AMD 和 RequireJS 将项目从 Dojo 1.6.1 升级到带有新 AMD 加载程序的 Dojo 1.7.1。我必须处理旧的 javascript 文件,而不是作为 AMD 模块编写的,并且必须以正确的顺序加载它们。

在我使用 RequireJS 订单插件之前,它似乎不适用于 Dojo AMD Loader。我在 loader 文档或 Dojo Build System 文档中找不到任何关于它的信息。

对此有什么想法吗?如果没有订单插件,我应该如何与 Dojo 1.7 一起处理纯 JavaScript 文件?我需要单独处理它们,还是在加载器或构建系统中有这方面的功能?

【问题讨论】:

你说的是无模块文件还是老式同步模块? 只是普通的 JavaScript 文件,比如 jQuery(不用作 AMD 模块),以任何样式编写。 【参考方案1】:

我自己只是在学习,但我找到的文档引用了Generic Script Injection

按照文档中的说明加载您的通用脚本,同时将 async: 0 指定为 require() 的配置选项。据我了解,这会按照您在第二个参数(包含脚本文件名/路径的数组)中指定的顺序加载脚本

我的例子:

require(async:0,['test1.js','test2.js','test3.js'],function()
    //do stuff with reference to loaded scripts

);

我的本​​地测试显示,如果我将配置更改为 async: 1,脚本加载的顺序与我指定的顺序不同。到目前为止,我还没有在 dojo 加载程序代码中追踪到这一点,但它似乎是有道理的,而且可以工作,而且不是 hack。

【讨论】:

我接受这个答案,因为它有效!我以这种方式创建了一个“依赖模块”:define(["require"], function(require) require(async:0, [ "script1.js", "script2.js", "script3.js" ]); );。我认为这是一个好的解决方案。谢谢! 有一点需要注意。我没有进一步调查它,但似乎(至少当您在如上所述的单独模块中加载脚本时)脚本加载在不同的范围内,而不是通过传统的脚本标签加载。例如,我必须将var uglyGlobal = true 替换为window.uglyGlobal = true async:1 配置的脚本注入方法使用注入的<script> 标记将脚本加载到 dom 中(您可以在 webkit 或 firebug 检查器中看到它们),因此加载脚本中的 vars可作为全局变量。我猜async:0 在自己的范围内加载脚本并评估它们?您是否尝试过通过嵌入 require 调用来定义您的依赖模块?类似于:define(["require"], function(requirerequire(['test1.js'],function(require(['test2.js'],function(require(['test3.js'],function())));); 可以按照您定义的顺序加载它们吗? 上面的示例加载为async:1,似乎对我有用,虽然我没有彻底测试 嗯,这是一个有趣的想法。也许可以编写一个 monad 来处理嵌套,然后可以编写类似requireChain("test1.js").then("test2.js").then("test3.js") 的东西。【参考方案2】:

我想为上述 cmets 中提到的这种依赖模块提出另一种方法。问题是define 不接受async 参数。在define 函数中使用简单的require 会引入竞争条件,因为所需模块的代码尚未执行。

示例(错误): oldCode.js

window.foo = 函数();

legacyWrapper.js

定义([“要求”],函数(要求) 需要(async:0,["./oldCode"]); )

code.js

定义([“./legacyWrapper”],函数() 窗口.foo(); //抛出异常,foo还没有被加载。 )

(jsFiddle demo)

但是,这个问题有一个解决方案。您需要返回一个Deferred,它会在所有模块加载后立即得到解决。以下示例按顺序加载 a,b,c,d。

define(["require","dojo/Deferred"],function(require,Deferred) var def = new Deferred(); 要求(异步:0, ["./moduleA", "./moduleB", "./moduleC", "./moduleD"], 功能() def.resolve(); ); 返回定义; )

要访问 moduleA 中定义的属性,您现在可以使用

需要([“legacyDeps”],函数(legacyDeps) legacyDeps.then(function() //这里假设所有的遗留模块都已经加载了。 ); );

【讨论】:

【参考方案3】:

我认为插件通常不兼容 AMD 加载程序。这不是最佳的,但您可能可以使用 dojo/text!与评估。这将在构建时内联内容。

【讨论】:

你的意思是这样吗? define([ "text!myScript", "text!myScript2" ], function(s, s2) eval(s); eval(s2) ) 它有效,我在 doh 测试中使用它,但我不愿意将其标记为已接受的答案,这是一个 hack =)

以上是关于RequireJS 订单插件和 Dojo 1.7.1的主要内容,如果未能解决你的问题,请参考以下文章

Dojo 增强网格嵌套排序无法排序

Dojo 和模板解决方案

使用requireJS的shim参数 解决插件 jquery.ui 等插件问题

在 dojo 1.7.2 中构建

使用插件将RequireJS / AMD迁移到Webpack

RequireJS文本插件:无法从其他域加载HTML