如果我正确理解了您的问题,您正在尝试编译您的 awesomeGame.js - 它依赖于threejs.js - 但是您对threejs.js 的引用被闭包的重命名过程破坏了。
我同意自动化外部脚本可能还有很多开发工作,可能不是一个可靠的解决方案。
我的项目有一个非常相似的问题。我可以提供两种可能的解决方案。每个都有取舍。我个人不是threejs用户,这里只说明一般约定。
1)从window对象开始,用括号语法调出你需要的对象
根据this discussion,在库执行并将其根对象放置在全局上下文中之后,您可以从window 开始找到它 - 并且永远不会重命名窗口对象。此外,括号语法永远不会被重命名。因此,您的编译代码可以在window['THREE'] 和THREE.Geometry 在window['THREE']['Geometry'] 中找到THREE,等等。此外,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');
如果您在漂亮/高级模式下将上述内容粘贴到Compiler Service,您会产生以下内容。
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 错误,并将它们括起来。如果你忘记了什么,编译器会提醒你。 Error Reference.
如果您的linter 对所有括号感到不满,请使用--sub 说服它,如“容忍下标”。 All jsLint errors/options.
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 cmets 和大量的console.log,你就会掌握它。
最后,根据threejs 的优先级和代码约定,Closure 中的编译可能不受支持,或者可能会引入细微的行为变化。如果是这种情况,请排除此选项。例如,jQuery 与闭包的兼容性是 actively being discussed。
无论如何,我希望这能回答你的问题。如果我不符合要求,请回复。那里也有很多“包含/模块化”框架。也许有人可以填写该主题。