我需要在ADVANCED模式下使用闭包编译器编译我的代码。我还需要在我的应用程序中保留我的对象的原型,因为我在Javascript对象原型上循环。尝试在启动应用程序时获得两个ReferenceError的结果。
使用ADVANCED模式进行编译时,会删除一些原型并替换为使用对象参数的函数,以便恢复"这个"关键词。这是由于CompilerOptions.java的crossModuleCodeMotionNoStubMethods属性。
编译前的代码示例:
function MyClass() = { // Some code }
MyClass.prototype.someFunc = function() { // Some code calling someOtherFunc };
MyClass.prototype.someOtherFunc = function(someParam) { // Some code };
编译后的代码示例:
function MyCompiledClass = { // Some code }
MyCompiledClass.prototype.someCompiledFunc = function() { // Some code calling someOtherFunc }
function someOtherCompiledFunc(that, someParam) = { // Some code }
我首先尝试使用@this和@preserve JSDoc标记来解决问题,但没有成功。使用@export不是解决方案,因为函数将保留其原始名称。
我现在找到了两个解决问题的方法:
选项1需要对我的代码进行大量修改,并且会降低其可读性,如果它是唯一的解决方案,我将会对此进行修改。
选项2似乎是一个很好的解决方法,但我已经读过CompilationLevel.java上的一些更改可能会违反编译器的某些核心假设。有人可以告诉我,如果将setCrossModuleMethodMotion从true修改为false,它是否仍会尊重编译器的所有核心假设?
我目前正在构建编译器的自定义版本以检查代码是否正确编译,但即使代码可用,我也需要确保它将被正确混淆。
谢谢!
答案 0 :(得分:0)
您指的具体优化过程是DevirtualizePrototypeMethods
。阻止优化的最佳方法是使用@nocollapse
注释。它将允许重命名您的方法,但不允许从原型中删除它。
我并非100%确定它适用于此案例,但如果它不适用,您可以提出问题以解决此问题:https://github.com/google/closure-compiler/issues
答案 1 :(得分:0)
您可以以相同的方式导出构造函数和原型属性。 例如:
MyClass = function(name) {
this.myName = name;
};
MyClass.prototype.myMethod = function() {
alert(this.myName);
};
window['MyClass'] = MyClass; // <-- Constructor
MyClass.prototype['myMethod'] = MyClass.prototype.myMethod;
与https://developers.google.com/closure/compiler/docs/api-tutorial3
一样