我正在使用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");
}
}
})();
答案 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/discussion和https://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加载器的未定义函数/变量问题。