17

我们正在尝试将项目的包装从 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 找不到:foo.bar
foo 未定义

当我查看 Net 选项卡时,没有 http 请求来获取文件 - 我期待闭包库生成一个脚本标记来 fetch bar.js

帮助!;)

4

7 回答 7

14

我想通了,这不是很难,但有一些陷阱。

基本上,您可以在以下几种模式之一中使用依赖生成脚本 calcdeps.py(您应该阅读 calcdeps.py 文档):

  1. 生成 deps.js 文件
  2. 将所有内容连接到一个文件中,可选择使用闭包编译器对其进行编译。

对于开发,您应该使用 (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的路径(这很重要!),第二个数组是goog.provide-d 字符串列表,最后一个数组是列表goog.require-d 字符串。

现在在 app.html 我有:

<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>

笔记:

  1. 除了包含闭包的 base.js 之外,我还包含了我生成的 deps.js
  2. 如教程中所述,goog.require调用必须在单独的 script 标签中,因为它附加了一个 script 标签来加载所需的脚本,并且在当前 script 标签完成处理后加载它们。

陷阱:

  1. 上述路径相对于 base.js 的问题。goog.require通过连接 base.js 基本 URL(即没有 base.js 叶名)和 deps.js 中 goog.addDependency 的第一个参数来创建要加载的脚本 URL。
  2. calcdeps.py 在 Windows 上不能很好地工作,特别是在 deps.js 字符串文字中使用反斜杠
  3. 如果某些事情不能正常工作,您可能需要查看所有提到 calcdeps 的问题,并确保您有最新的结帐。
于 2010-01-05T16:09:25.790 回答
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 一起使用,所以这也很有趣。一些 hack 让它对我有用(我不会放在这里,因为我不是 python 程序员,必须有更好的方法来做到这一点)。

总的来说,最后一天非常有趣,希望这篇文章能帮助人们避免同样的享受。

圭多

于 2010-07-14T21:46:09.043 回答
1

通过将以下内容添加到以下内容,我能够使其工作deps.js
goog.addDependency('../../../foo/bar.js', ['foo.bar'], []);

/foo/bar.jsFirefox 现在会在遇到该goog.requires语句时发出 http 请求。

但是,该文件包含以下注释:
// This file has been auto-generated by GenJsDeps, please do not edit.

据此GenJsDeps一样的calcdeps.py。如果您查看文档,似乎有一个-o deps将重新生成的开关,deps.js因此无需手动编辑。

于 2009-12-17T05:15:46.333 回答
1

是的,您应该使用 calcdepds.py。经过多次尝试和错误后,我创建了一篇大型博客文章,以找出最好的方法,我还讨论了 dojo.require 和 goog.require 之间的区别:

http://apphacker.wordpress.com/2009/12/28/howto-how-to-use-goog-require-and-goog-provide-for-your-own-code/

于 2009-12-28T23:39:42.320 回答
0

这是我一直在做的一个小项目,可能对你有帮助:http: //github.com/fintler/lanyard

查看 build.xml、名为 lanyard.js 的文件以及位于 src/geom/* 中的所有文件。

build.xml 中有一个示例,说明如何通过 ant 为 src 中的所有 js 调用 calcdeps.py。这可能不是最好的做事方式,但到目前为止它一直对我有用。

于 2010-02-23T17:32:21.607 回答
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 源代码编译来获得闭包库的所有好处。

于 2010-11-11T11:58:28.693 回答
0

解决方案:

  • 将闭包下载到您的项目外部(或资产,等等)。

  • 不要费心设置onload,延迟,玩异步等。

  • 他们不会工作(他们的设计模式也很差,而且非常蹩脚..)

- 这是您main.js将代码动态注入 DOM 的地方(例如创建书签或其他东西):

/**
 * 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);
  • 您的“回调”只是在文件完成渲染时激活启动器,

  • 它工作得很好,并且它保持异步加载每个资源。

ps

  1. window['....'] 语法使您可以安全地最大程度地使用闭包编译器并始终使用相同的名称(尽管还有其他方法可以这样做,但这是简单的“始终有效”的方法。 .)。

2.base.js你也可以避免超时,只需使用

......
.......
........

/**
 * run the method when done load. just like JSONProtocol.
 */
window['starter']();

但根据经验,现代浏览器在包装那些“不在乎,只在最后做这些事情,比如 JSONProtocol 回调”的东西时会表现得更好 -

超时(通常与 0-5 的值一起使用)不会作为超时中断,而是作为打破代码块同步性的一种方式,允许真正的“上下文切换”行为。

尽管那里有额外的开销。

于 2013-06-21T02:12:32.540 回答