如果我正确理解了您的问题,那么您正在尝试编译您的 awesomeGame.js - 它依赖于threejs.js - 但是您对threejs.js 的引用被闭包的重命名过程破坏了。
我同意自动化外部脚本可能有很多开发工作,可能不是一个强大的解决方案。
我的项目有一个非常相似的问题。我可以提供两种可能的解决方案。每个都有取舍。我个人不是threejs用户,这里只说明一般约定。
1)从window对象开始,用括号语法调出你需要的对象
根据这个讨论,在库执行并将其根对象放置在全局上下文中之后,您可以通过从window
- 开始找到它,并且窗口对象永远不会被重命名。此外,括号语法永远不会被重命名。因此,您的编译代码可以THREE
在 atwindow['THREE']
和THREE.Geometry
atwindow['THREE']['Geometry']
等处找到。此外,jQuery 将在 window['jQuery'] 中找到,并在 window['_'] 处找到下划线。
我建议任何时候你需要从编译的代码中访问外部对象或函数,比如threejs.js,在文件顶部声明一些全局定义,如下所示:
// awesomeGame.js:
// global defines:
var three_vertex = window['THREE']['Geometry']['vertex'],
three_rectangle = window['THREE']['Geometry']['rectangle'],
three_crossproduct = window['THREE']['Math']['crossproduct'],
jquery_ajax = window['jQuery']['ajax'];
// game assets:
var myVertex = new three_vertex(10,10),
myRectangle = new three_rectangle(10,10,10,10);
// do stuff:
console.log(myVertex['x'] + ' ' + myVertex['y']);
console.log(three_crossproduct(myVertex, myVertex));
myRectangle['paint']('black');
如果您将以上内容粘贴到漂亮/高级模式下的编译器服务,您将产生以下内容。
var a = window.THREE.Geometry.rectangle,
b = window.THREE.Math.crossproduct,
c = new window.THREE.Geometry.vertex(10, 10),
d = new a(10, 10, 10, 10);
console.log(c.x + " " + c.y);
console.log(b(c, c));
d.paint("black");
正面:
完整的threejs.js 引用仅在全局定义中打印一次。从那时起,闭包将打印一个容器“a”或“b”。因此,与您讨论的外部方法不同,您可以获得大部分压缩优势。
否定:
threejs.js 对象的方法和属性 - 必须在括号语法中一致地命名。请注意,如果 ['x'] 和 ['y'] 属性以及 ['paint'] 方法没有被括号括起来,它们将被重命名。将 Closure 设置为--warning_level=VERBOSE
,注意JSC_INEXISTENT_PROPERTY
错误,并将它们括起来。如果你忘记了什么,编译器会提醒你。错误参考。
如果你的linter对所有的括号都不满意,用 说服它--sub
,就像“容忍下标”一样。所有 jsLint 错误/选项。
2) 将threejs.js 和 awesomeGame.js 连接成一个temp.js
另一种方法:为自己设置一个构建脚本,将所有源文件按依赖顺序连接到一个大临时文件中。如果您是 unix-y,您的脚本可能如下所示:
#!/bin/bash
# build_and_run.sh
# get updates to google closure: http://code.google.com/p/closure-compiler/downloads/list
#
# local jslint:
# sudo apt-get install nodejs npm
# sudo npm jslint -g
rm temp.js
rm final.js
cat threejs.js \
awesomeGame_moduleOne.js \
awesomeGame_moduleTwo.js \
> temp.js
# docs: http://www.jslint.com/lint.html
jslint temp.js \
--maxerr=50 --sloppy --white --sub --plusplus \
--nomen --bitwise --browser \
--predef unescape \
--predef Uint8Array \
--predef Blob
java -jar compiler-20130823.jar \
--compilation_level ADVANCED_OPTIMIZATIONS \
--formatting pretty_print \
--language_in=ECMASCRIPT5 \
--js temp.js \
--js_output_file final.js
#maybe
nodejs final.js
# or
# https://developers.google.com/chrome/web-store/docs/get_started_simple
chromium --load-and-launch-app=./
# rinse, repeat
优点:
没有括号,没有定义,没有扩展,没有中间件。谷歌关闭看到了一切。最终产品的最大压缩。运输项目的完整 linting(扫描原始的、分割的源文件可能会使 linter 感到困惑)。发送单个集成文件。
负面:
沉浸在上游源代码中。这可能会或可能不会让您同意。对上游源代码进行检查会特别诱使您在上游强加代码样式。反抗,反抗。另一方面,了解您所依赖的中间件具有优势。
还涉及调试 master.js 文件,因为将为 final.js 报告行号,并且您需要在阅读时识别源文件。使用漂亮的模式、更温和的编译设置、 @preserve
注释和大量的console.log
,你会得到它的处理。
最后,根据 threejs 的优先级和代码约定,可能不支持 Closure 中的编译,或者可能会引入细微的行为变化。如果是这种情况,请排除此选项。例如,正在积极讨论jQuery 与闭包的兼容性。
无论如何,我希望这能回答你的问题。如果我不符合要求,请回复。那里也有很多“包含/模块化”框架。也许有人可以填写该主题。