我们正在尝试将我们项目的包装从dojo切换到google关闭,但到目前为止我们还没有运气。这是一个简单的例子,说明了我们要完成的任务:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script type="text/javascript" src="runtime/src/core/lib/goog-rev26/base.js"></script>
<script>
goog.require("foo.bar");
function main() {foo.bar.echo("hello world")}
</script>
</head>
<body onload="main()">
</body>
</html>
然后在/foo/bar.js
我有:
goog.provide("foo.bar");
foo.bar.echo = function(s) {console.debug(s);}
我在firebug中收到的错误如下:
goog.require could not find: foo.bar foo is not defined
当我查看Net选项卡时,没有提取文件的http请求 - 我希望闭包库生成一个脚本标记来获取bar.js
。
帮助! ;)
答案 0 :(得分:13)
我想出来并且不是很难,但有一些陷阱。
基本上,您可以在以下几种模式之一中使用依赖关系生成脚本calcdeps.py(you should read calcdeps.py docs):
对于开发,您应该使用(1),因为它允许您在编辑JS源之后不运行calcdeps.py,除非您对依赖关系树进行了更改。其余的答案是这样的,我还没有尝试过另一个。
以下是我为此制作的内容:
#!/bin/bash
cd closure-library/closure/goog
python ../bin/calcdeps.py -p ../../../js -o deps > ../../../my-deps.js
...假设以下目录结构:
project/
closure-library/ (as checked out from SVN)
js/ (my JS code)
app.html
(-p
参数遍历指定目录中的所有js文件,文档说您可以指定多个目录进行搜索(如果必须)。)
上面的调用会在主app.html旁边创建一个my-deps.js文件,用于运行该应用程序。创建的文件包含js/
中有关我的JS文件的信息,如下所示:
goog.addDependency('../../../js/controllers.js', ['proj.controllers'], []);
goog.addDependency('../../../js/ui.js', ['proj.ui'], ['proj.controllers']);
- 第一个字符串是我的JS文件的路径相对于closure-library / closure / goog / base.js (这很重要!),第二个数组是{的列表{1}} - d字符串,最后一个数组是goog.provide
- d字符串列表。
现在在app.html中我有:
goog.require
注意:
goog.require
call has to be in a separate script tag中所提到的,因为它附加了一个脚本标记来加载所需的脚本,并在当前脚本标记处理完毕后加载它们。陷阱:
<script src="closure-library/closure/goog/base.js"></script>
<script src="my-deps.js"></script>
<script>
goog.require("proj.ui");
</script>
<script>
// here we can use the required objects
</script>
通过将base.js基本URL(即没有base.js leafname)和第一个参数连接到deps.js中的goog.addDependency来创建要加载的脚本URL。答案 1 :(得分:8)
更新!!!
新版本的calcdeps.py稍微改变了游戏规则。要创建deps.js,您现在需要使用-d标志。例如:
python path-to-closure-library/closure/bin/calcdeps.py -i path-to-your-src/requirements.js -o deps -d path-to-closure-library/closure/ -p path-to-your-src/ --output_file=path-to-your-src/deps.js
编译:
python path-to-closure-library/closure/bin/calcdeps.py -i path-to-your-src/requirements.js -d path-to-closure-library/closure/ -p ./ --output_file=path-to-your-release/scripts.min.js -c path-to-compiler/compiler.jar -f "--compilation_level=ADVANCED_OPTIMIZATIONS" -f "--debug=true" -f "--process_closure_primitives=true" -f "--manage_closure_dependencies=true" -o compiled
所以这个过程实际上现在变得容易多了,但是你必须利用ESP的力量来发现它完全没有文档。 calcdeps.py现在也无法在Windows上使用Python 3.1,因此这也是很有趣的。一些黑客让它为我工作(我不会放在这里,因为我不是一个python程序员,必须有更好的方法来做到这一点。)
一般来说,最后一天非常有趣,希望这篇文章可以帮助别人避免同样的享受。
圭
答案 2 :(得分:1)
我可以通过将以下内容添加到deps.js
来使其工作:
goog.addDependency('../../../foo/bar.js', ['foo.bar'], []);
当Firefox遇到/foo/bar.js
语句时,它会向goog.requires
发出http请求。
但是,该文件包含以下评论:
// This file has been auto-generated by GenJsDeps, please do not edit.
根据this,GenJsDeps
与calcdeps.py
相同。如果您查看文档,看起来有一个-o deps
开关会重新生成deps.js
,因此不会手动编辑。
答案 3 :(得分:1)
是的,你应该使用calcdepds.py。经过多次试验和错误后我创建了一篇很棒的博客文章,找出了最好的方法,我也回顾了dojo.require和goog.require之间的差异:
答案 4 :(得分:0)
这是我一直在努力的一个小项目,可能对您有所帮助:http://github.com/fintler/lanyard
查看build.xml,名为lanyard.js的文件以及位于src / geom /*中的所有文件。
build.xml有一个如何通过ant为src中的所有j调用calcdeps.py的示例。这可能不是最好的做事方式,但到目前为止它一直在为我工作。
答案 5 :(得分:0)
无论哪种方式使自定义模块工作,至少对于开发版本,都是在google的base.js文件包含之后在html页面的head部分包含手动js文件。
<script type="text/javascript" src="js/closure/goog/base.js"></script>
<script type="text/javascript" src="js/closure/custom/custom.js"></script>
<script type="text/javascript" src="js/closure/custom/sub/sub.js"></script>
...
但是,你应该自己关心包容的顺序。对于不是很大的自定义文件集,它运行良好。对于生产版本,您仍然最好使用js源代码编译来获得闭包库的所有好处。
答案 6 :(得分:0)
溶液:
将关闭下载到您的项目外部(或资产,无论如何)。
不要打扰设置onload,延迟,玩异步等等。
他们不会工作(他们的设计模式也非常差,非常蹩脚......)
main.js
(例如创建书签或其他内容):/**
* loads the base.js of google closure.
* http://code.google.com/p/closure-library/
*/
(function() {
var s = document.createElement('script');
s.type = "text/javascript";
s.src = "./assets/closure/goog/base.js";
s.async = true;
document.getElementsByTagName("body")[0].appendChild(s);
}());
/**
* activated from the base.js as JSONProtocol.
*/
window['starter'] = function() {
console.log("hi...");
};
现在:
base.js
添加文件末尾
......
.......
........
/**
* run the method when done load. just like JSONProtocol.
*/
window.setTimeout(function() {
window['starter']();
}, 5);
您的“回调”只需在文件完成渲染后激活启动器,
它完美无缺,并且不断异步加载每个资源。
P.S。
base.js
上你也可以避免超时并只使用......
.......
........
/**
* run the method when done load. just like JSONProtocol.
*/
window['starter']();
但是根据经验,现代浏览器在包装那些“不关心,最后只做这些东西,比如JSONProtocol回调”的东西时效果会更好 -
超时(主要用于0-5的值)不会因为超时而中断,而是作为一种打破代码块同步性的方法,允许真正的“上下文切换”行为。
虽然那里有额外的开销。