Google Closure Compiler高级:在编译时删除代码块

时间:2010-11-12 17:44:32

标签: javascript google-closure-compiler

如果我使用此代码并进行编译(高级优化)

/**@constructor*/
function MyObject() {
    this.test = 4
    this.toString = function () {return 'test object'}
}
window['MyObject'] = MyObject

我收到此代码

window.MyObject=function(){this.test=4;this.toString=function(){return"test object"}};

有没有办法可以使用Closure Compiler删除toString函数?

3 个答案:

答案 0 :(得分:3)

toString是可隐式调用的,因此除非Closure编译器能够证明MyObject的结果永远不会被强制转换为字符串,否则它必须保留它。

您始终可以将其标记为显式调试代码:

this.test = 4;
if (goog.DEBUG) {
  this.toString = function () { return "test object"; };
}

然后在非调试版本中,使用

进行编译
goog.DEBUG = false;

请参阅<{3}}

/**
 * @define {boolean} DEBUG is provided as a convenience so that debugging code
 * that should not be included in a production js_binary can be easily stripped
 * by specifying --define goog.DEBUG=false to the JSCompiler. For example, most
 * toString() methods should be declared inside an "if (goog.DEBUG)" conditional
 * because they are generally used for debugging purposes and it is difficult
 * for the JSCompiler to statically determine whether they are used.
 */
goog.DEBUG = true;

答案 1 :(得分:0)

答案非常简单。我正在研究此问题,但未找到正确的答案,因此在此处添加它。解决方案是使用JSDoc注释(请参见https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#const-const-type):

/* @const */
const debug = false;

现在,在代码中的任何地方(也在嵌套函数内部),您都可以执行以下操作:

if (debug) console.log("hello world");

或者就您而言,使一个完整的区块无效

if (debug) {
    /* your code to remove */    
}

如果将debug设置为false,那么Closure编译器可以删除它,因为它知道您声明了debug常量a,因此它不会更改,并且如果用您的debug变量进行门操作,则代码将永远不会执行。

答案 2 :(得分:0)

由于@define在模块中不起作用,我编写了一个补丁,可以在编译之前运行它。它会:

import { c } from '@artdeco/erte'
import { readFileSync, writeFileSync } from 'fs'
import { join } from 'path'

const [,,version] = process.argv

const PATH = join(__dirname, 'index.js')
let f = readFileSync(PATH, 'utf-8')

const isFree = version == '--free'

if (isFree) {
  f = f.replace("\nimport isFree from './paid'", "\n// import isFree from './paid'")
  f = f.replace("\n// import isFree from './free'", "\nimport isFree from './free'")
  console.log('Set version to %s', c('free', 'red'))
} else {
  f = f.replace("\n// import isFree from './paid'", "\nimport isFree from './paid'")
  f = f.replace("\nimport isFree from './free'", "\n// import isFree from './free'")
  console.log('Set version to %s', c('paid', 'magenta'))
}

writeFileSync(PATH, f)

用法: 节点./src/version/patch --free 节点./src/version/patch --paid

正在修补的实际./src/version/index.js

// import isFree from './free'
import isFree from './paid'

带有'./free':

export default true

带有“ ./付费”:

export default true

基于此,您可以从index.js导出变量:

export const free = isFree

这是为了允许编译付费和免费软件包,但是您可以扩展此代码以调整调试/生产版本。

尽管如此,应该使用-D(@define)来完成,但显然对于像Google这样的市值达数万亿美元的公司来说,这是非常困难的。