gpt4 book ai didi

javascript - Google Closure 编译器的 ADVANCED_OPTIMIZATIONS 选项

转载 作者:行者123 更新时间:2023-11-29 16:21:31 24 4
gpt4 key购买 nike

我最近一直在检查 Google Closure Compiler。我下载了 .jar 文件并进行了试用。到目前为止,我必须说我印象非常深刻。我当然可以看到它超越最小化的用处。支持 Google 团队!

不过我确实有一个小提示。在我看来,就优化而言,您只有两个选择。它是 SIMPLE_OPTIMIZATIONS 或 ADVANCED_OPTIMIZATIONS。前者虽然足够,但非常简单恕我直言。一方面,除非我遗漏了什么,否则它不会影响所有属性名称。它也不会删除无法访问的代码。另一方面,后一种选择的破坏性太大。

现在,我对 JavaScript 还很陌生,所以我很可能遗漏了一些东西。如果我说了一些愚蠢的话,请随时给我上课。也就是说,我可以理解在 JavaScript 中重命名的问题。 Google 团队建议使用括号表示法 (object['property']) 而不是点表示法 (object.property) 来访问您不想更改的属性,并且永远不要混合使用这两种用法。他们还建议使用以下模式“导出”方法:

MyClass = function(name) {
this.myName = name;
};

MyClass.prototype.myMethod = function() {
alert(this.myName);
};

window['MyClass'] = MyClass; // <-- Constructor
MyClass.prototype['myMethod'] = MyClass.prototype.myMethod;

但是,在某些合法的情况下,您希望混合使用这两种表示法。假设我们正在构建一个游戏。游戏代码完全隔离在一个闭包中。它不会将任何内容“导出”到全局范围,也不需要。事实上,它真的不应该接触窗口对象。但是,它确实需要从 XML 配置文件中读取一些游戏内属性。

示例 JavaScript:

var TheGreatAdventure = (function(window) {

function Fighter() {
// Private to application
this.id = 42;
// Accessible to XML configuration system
this.name = 'Generic Jen';
this.hitPoints = 100;
this.onAttack = genericFighterAttack;
this.onSpeak = genericFighterSpeak;
...
}
Fighter.publishedProperties = ['name', 'hitPoints', 'onAttack', 'onSpeak']

function genericFighterAttack() {...}
function genericFighterSpeak() {...}

function cassieAttack() {...}
function cassieSpeak() {...}

...

EntityReader = {
...
function readFromXMLNode(attributes, entityClass, entityInstance) {
for (var i = 0; i < attributes.length; i++) {
var attribute = attributes[i];
if (attribute.nodeName in entityClass.publishedProperties)
entityInstance[attribute.nodeName] = bindContext[attribute.value];
}
}
...
}

}(window));

示例 XML 配置文件:

<Fighter name='Custom Cassie' onAttack='cassieAttack' onSpeak='cassieSpeak'/>

不仅上述系统无法分配属性,函数 cassieAttack 和 cassieSpeak 将在最小化期间​​作为死代码被删除!

现在,我无法在整个游戏代码中使用括号表示法访问所有“已发布”属性。即使这样做没有运行时惩罚(不应该有任何惩罚),仍然需要进行大量额外的输入,而且(IMO)这是一个碍眼的问题。有了这些共同的属性,所有内容都会在文本编辑器中显示为字符串,从而违背了语法高亮的目的!

在我看来,对这些属性的一个简单的@preserve(或类似的东西)指令将允许在最终程序大小中以最小的成本使用 ADVANCED_OPTIMIZATIONS。我错过了什么吗?

最佳答案

这个答案被完全重写,原来有一种方法可以做 user1127813 想要的。

您需要提供一个属性映射文件,使用 --property_map_input_file 标志将一些名称映射到它们自己。假设你在test.js中有如下原始代码:

/** @constructor */
function Fighter() {
this.ID = 42;
this.fullName = 'Generic Jen';
this.hitPoints = 100;
}
Fighter.publishedProperties = ['fullName', 'hitPoints'];

var jen = new Fighter();
var bob = new Fighter();

bob.ID = 54;
bob.fullName = 'Bob the Destructor';
bob.hitPoints = 1337;

for(i = 0; i < Fighter.publishedProperties.length; i++) {
prop = Fighter.publishedProperties[i];
alert(prop + ' = ' + bob[prop]);
}

这样编译:

java -jar closure-compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js test.js --property_map_output_file testprop.txt --js_output_file test2.js

您将获得一个新文件 test2.js(包含无效的内容)和另一个包含以下内容的文件 testprop.txt:

ID:a
hitPoints:c
fullName:b

更改 testprop.txt 使其看起来像这样:

ID:ID
hitPoints:hitPoints
fullName:fullName

然后用testprop.txt作为输入而不是输出重新编译:

java -jar closure-compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js test.js --property_map_input_file testprop.txt --js_output_file test2.js

观察test2.js的内容:

var a=["fullName","hitPoints"],b=new function(){};b.ID=54;b.fullName="Bob the Destructor";b.hitPoints=1337;for(i=0;i<a.length;i++)prop=a[i],alert(prop+" = "+b[prop]);

现在可以使用圆点表示法以其原始名称访问所需的属性,程序将正确显示包含 bob 已发布属性的弹出窗口。

关于javascript - Google Closure 编译器的 ADVANCED_OPTIMIZATIONS 选项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10433716/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com