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

问题描述:

我正在使用Dojo并使用Mastering Dojo中描述的“模块模式”。就我所见,这种模式是一种广泛使用的JavaScript模式。我的问题是:我们如何调试我们的模块?JavaScript/Dojo模块模式 - 如何调试?

到目前为止,我还没有能够说服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"); 
      }   
     } 
})(); 

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

看来,一个可以在Firebug调试很好EVAL-ED代码提供了道场确实有点合作。诀窍是配置道场使用debugAtAllCosts

<script type="text/javascript" src="/dojoroot/dojo/dojo.js" 
     djConfig="parseOnLoad: true, debugAtAllCosts: true"></script> 

,使这种调试这debugging,其还指出,在生产性能方面的原因,不推荐此设置,建议使用服务器的方法下的道场校园描述以控制是否启用此类调试。

+0

debugAtAllCosts在FF和WebKit上通常不再需要,因为我的回答中提到的原因 – peller 2010-04-13 17:19:47

+0

我只能说没有这里显示的djconfigs,调试器显示“eval”行而不是eval-ed代码,步进是没有用。我用djconfig显示完整的源代码是可见的,我可以很好地进行分析。 – djna 2010-04-14 05:36:46

+0

在Chrome中,我发现我能够调试我的模块的源代码,但不能在Firebug(1.8)中使用,所以这个答案相当省时,谢谢。 – mydoghasworms 2011-10-19 07:50:11

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

我不知道为什么这些都不会为你工作。你使用的是哪个版本的Firebug?

+0

使用Firebug 1.5.3 - 我想我已经找到了一个答案:debugAtAllCosts,稍后会发布。 – djna 2010-04-13 15:23:57

+0

不适用于Firebug 1.8,尽管使用Chrome。这里接受的答案为我工作。 – mydoghasworms 2011-10-19 07:52:15

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,对我来说萤火1.6。1将带我到右边的eval块,但不是正确的文件和行号(因为它是一个评估字符串,而不是原始文件)..

此外,如果您使用的是Firebug版本低于1.7a10验证脚本下拉禁用(extensions:firebug.decompileEvals在about:config中)的“Decompile for eval()源”。启用时,我认为这会导致Firebug用自己的反编译版本覆盖源文件,并且沿途也会丢失文件名。

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

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

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

我会再添加一个替代方案,使用Chrome。调试evals非常好(似乎可以捕捉到Firebug没有的东西)。请注意缓存JS文件的问题 - http://code.google.com/p/chromium/issues/detail?id=8742

个人萤火虫仍然是我的主要环境,但我现在也在使用Chrome浏览器时,事情变得棘手与evals得到第二个问题的看法。 Chrome昨天帮助我两次,用Firebug跳过的dojo加载器的未定义的函数/变量问题)。

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

变化

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

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

此固定小于有用 undefineddojo._scopeArgs = [未定义];否则看到的 错误。