0

我正在阅读Addy Osmani关于编写 AMD 模块的优秀博文。我从从他的帖子中提取的一小段 js 开始:

define('modTest', [],
  // module definition function
  function () {
      // return a value that defines the module export
      // (i.e the functionality we want to expose for consumption)

      // create your module here
      var myModule = {
        doStuff:function(){
          console.log('Yay! Stuff');
        }
      }

      return myModule;
  }
);

foo我去掉了对and的依赖bar。只想要一个记录到控制台的简单对象。

所以我将其保存,/js/modTest.js然后尝试加载它:

curl(['/js/modTest.js'])
 .then(function(mt) {
     console.log("Load complete"); 
     console.log("mt:"); 
     console.log(mt); 
     mt.doStuff()
  }, function(ex) {alert(ex.message);})

结果:错误:Multiple anonymous defines in URL。好的,那没有用。尝试在命名空间中添加:define('myCompany/modTest', [],,同样的结果。尝试在依赖数组中添加一个空字符串,结果相同。

也尝试curl(['modTest.js'], function(dep){console.log(dep)});了相同的结果。

Addy 博文中的代码不正确吗?难道我做错了什么?也许卷曲中的错误?

5/24 更新:我放弃了 curl.js 以支持 require.js。零奇怪的错误,很少有工作需要改变。我确实需要处理一些 amdefine 来让我的代码在客户端和服务器端运行(两个地方都有一个对象,所以必须配置 grunt 来处理这个问题)。我的定义通常如下所示:

define(->
    class AlphaBravo 
    ... 

并且永远不会有任何问题加载。

4

3 回答 3

1

您要求 curl() 获取名为“/js/modTest.js”的模块。它找到了文件并加载了它,并找到了一个名为“modTest”的模块,所以它抱怨了。:) (不过,该错误消息非常错误!)

以下是修复它的方法(选择一个):

1) 从您的define() 中删除ID。不建议使用身份证。它通常仅由 AMD 构建工具和在测试工具中声明模块时使用。

2) 通过您在define() 中提供的ID 引用模块。(同样,在大多数情况下不建议使用 ID。)

curl(['modTest'], doSomething);

3) 将包(或路径)映射到包含应用程序模块的文件夹。我不清楚你的例子会是什么,因为 modTest 似乎是一个独立的模块。但是,如果您决定将应用程序的文件组织在“应用程序”包下,您的包配置可能如下所示:

packages: [ { name: 'app', location: 'app' } ]

然后,当您有依赖于 modTest 模块的代码时,您可以通过“app/modTest”的 ID 访问它。

curl(['app/modTest'], doSomething);

我希望这有助于澄清事情!

Fwiw,Addy 的示例实际上可以使用正确的配置,但我在那篇文章中没有看到任何配置(或者我的眼睛错过了它)。像这样的东西可能会起作用:

packages: [ { name: 'app', location: '.' } ]

- 约翰

于 2013-03-05T18:34:58.510 回答
0

我刚刚遇到了一个类似的问题,原来是我用于其他库的包含顺序。我以传统方式(头部中的脚本标签)将handlebars.js、crossroads.js、jquery和其他一些库加载到我的项目中,发现当我首先放置curl.js时,我得到了这个错误,但是当我最后包含它时,我没有收到此错误。

我的头部标签现在看起来像这样:

<script type="text/javascript" src="/js/lib/jquery.js"></script>
<script type="text/javascript" src="/js/lib/signals.js"></script>
<script type="text/javascript" src="/js/lib/crossroads.js"></script>
<script type="text/javascript" src="/js/lib/handlebars.js"></script>
<script type="text/javascript" src="/js/lib/curl.js"></script>
<script type="text/javascript" src="/js/main.js"></script>
于 2013-03-05T11:59:26.887 回答
0

你的define电话有问题。它被命名

有关如何编写定义的完整故事,请参阅AMD 规范,但这是我希望在您的js/modTest.js文件中看到的内容:

define(/* this is where the difference is */ function () {
      // return a value that defines the module export
      // (i.e the functionality we want to expose for consumption)

      // create your module here
      var myModule = {
        doStuff:function(){
          console.log('Yay! Stuff');
        }
      }

      return myModule;
  }
);

现在,无聊的解释:

CurlJS 很棒。事实上,在处理了 RequireJS 和 CurlJS 之后,我会说 CurlJS 在一个类别中比 RequireJS 更棒 - 脚本执行顺序的可靠性。所以你在正确的轨道上。

CurlJS 的主要不同之处在于它使用“为每个加载的模块查找至少一个匿名定义,否则为错误”逻辑。RequireJS 使用超时,它有效地忽略了在给定文件中没有定义任何内容的情况,但会因捕获的加载/解析错误而崩溃。

这种差异就是让你来到这里的原因。CurlJS 期望每个加载的模块至少有一个匿名(如未命名)定义。正如预期的那样,它仍然可以很好地处理命名定义。第二次将“js/modTest.js”的内容移动到内联代码中,您必须“命名”定义。但是,那是另一回事了。

于 2013-03-05T18:31:02.220 回答