JavaScript / Dojo模块模式 - 如何调试?

时间:2010-04-13 07:54:29

标签: javascript debugging dojo

我正在使用Dojo并使用Mastering Dojo中描述的“模块模式”。到目前为止,我可以看到这种模式是一种通用的,广泛使用的JavaScript模式。我的问题是:我们如何调试我们的模块?

到目前为止,我还没能说服Firebug向我展示我模块的来源。 Firebug似乎只显示用于执行工厂方法的dojo eval语句。因此,我无法单步执行我的模块源代码。我已经尝试在我的模块代码中加入“调试器”语句,Firebug似乎正常停止,但没有显示源代码。

下面的示例代码。这只是一个足够复杂的例子,使调试的需要变得合理,它并不是有用的代码。

页面

<!--
  Experiments with Debugging
-->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head> 
    <title>console me</title>

    <style type="text/css">
      @import "../dojoroot/dojo/resources/dojo.css";
      @import "../dojoroot/dijit/themes/tundra/tundra.css";
      @import "edf.css";
    </style>    

    <script type="text/javascript" src="../dojoroot/dojo/dojo.js">
    </script>

    <script type="text/javascript" >
      dojo.registerModulePath("mytest", "../../mytest");

      dojo.require("mytest.example");

      dojo.addOnLoad(function(){
         mytest.example.greet();                     
      });
    </script>

  </head>
  <body class="tundra">
    <div id="bulletin">
      <p>Just Testing</p>
    </div>
  </body>
</html>
<!-- END: snip1 -->

我想调试的java脚本

dojo.provide("mytest.example");
dojo.require("dijit.layout.ContentPane");

/**
 * define module
 */
(function(){
      //define the main program functions...
      var example= mytest.example;
      example.greet= function(args) {

          var bulletin = dojo.byId("bulletin");

          console.log("bulletin:" + bulletin);

          if ( bulletin) {
                var content = new dijit.layout.ContentPane({
                    id: "dummy",
                    region: "center"
                  });
                content.setContent('Greetings!');

                dojo._destroyElement(bulletin);
                dojo.place(content.domNode, dojo.body(), "first");
              console.log("greeting done");
          } else {
              console.error("no bulletin board");
          }           
      }
})(); 

6 个答案:

答案 0 :(得分:3)

(自己回答这个问题,因为这似乎是一个常见的问题,其解决方案并不为人所知。)

似乎可以很好地调试FireBug中的eval-ed代码,前提是dojo做了一点合作。诀窍是使用 debugAtAllCosts

配置dojo以启用此类调试
<script type="text/javascript" src="/dojoroot/dojo/dojo.js"
        djConfig="parseOnLoad: true, debugAtAllCosts: true"></script>

这是在debugging下的dojo校园中描述的,其中还指出,出于性能原因,不建议在生产环境中使用此设置,并建议使用服务器端条件控制是否启用此类调试的方法。

答案 1 :(得分:1)

模式本质上是xhr + eval ...真的是eval是问题... Firefox特别无法将eval中的代码跟踪回原始来源,而是指向eval call site, plus whatever line offset there is在eval缓冲区中。 Firebug已经实现了a clever scheme来解决这个问题,并添加了一个可选的提示,像Dojo这样的加载器可以用来在注释中嵌入原始文件路径。 Webkit现在也supports这个方案。它并不完美,但是debugger;和其他断点应该会带你进入正确的缓冲区。

我不确定为什么这些都不适合你。您使用的是哪个版本的Firebug?

答案 2 :(得分:1)

此外,如果您使用的Firebug版本低于1.7a10,还要验证脚本下拉列表中是否存在“devalile for eval()source”(about:config中的extensions.firebug.decompileEvals)。启用后,我认为这会导致Firebug用自己的反编译版本覆盖源代码,并且在某种程度上也会丢失文件名。

@peller,这可能就是为什么你的回答不适合我们。

默认情况下它被禁用,但我在某个时候打开它并且没有意识到它。

作为Firebug问题http://code.google.com/p/fbug/issues/detail?id=4035的一部分,它也将在1.7a10中完全删除。还有https://groups.google.com/d/topic/firebug/y2VR17IFHHI/discussionhttps://groups.google.com/d/topic/dojo-interest/nWlZdJDlic8/discussion的相关讨论。

答案 3 :(得分:1)

这是我找到的一个解决方案,因为无法通过读取NG来递归到dojo.require mudules。

更改

<script src="dojoroot/dojo/dojo.js" type="text/javascript">

<script src="dojoroot/dojo/dojo.js.uncompressed.js" type="text/javascript">

这解决了不太有帮助的问题     undefineddojo._scopeArgs = [undefined]; 否则就会出现错误。

答案 4 :(得分:0)

djna的debugAtAllCosts解决方案适用于我,原因在http://dojotdg.zaffra.com/tag/dojorequire/描述。

但是,请注意使用debugAtAllCosts会导致dojo.require变为异步,因为它使用脚本插入而不是xhr + eval。这可能导致代码的问题,这些代码期望dojo.require是同步的,而不是使用require本身(如http://kennethfranqueiro.com/2010/08/dojo-required-reading/所述)。在我的情况下,它是测试我由单元测试框架运行的代码。因此,以下未能说EntityInfo未定义

var e1 = new EntityInfo();

直到我将其更改为

dojo.addOnLoad(function() {
  var e1 = new EntityInfo();
}

@peller,对我来说,FireBug 1.6.1将把我带到正确的eval块,但不是正确的文件和行号(因为它是一个eval字符串而不是原始文件)..

答案 5 :(得分:0)

我将添加一个替代方案,使用Chrome。它对调试evals很有用(似乎抓住了Firebug没有的东西)。请注意缓存JS文件的问题 - http://code.google.com/p/chromium/issues/detail?id=8742

个人Firebug仍然是我的主要环境,但我现在也使用Chrome,当事情变得棘手时,我们会对问题进行第二次观察。昨天Chrome帮助我两次使用了Firebug跳过的dojo加载器的未定义函数/变量问题。