Javascript 闭包编译器删除的内容超过了我要删除的内容

Javascript 闭包编译器删除的内容超过了我要删除的内容,javascript,compiler-construction,closures,google-closure-compiler,Javascript,Compiler Construction,Closures,Google Closure Compiler,我已经从代码中删除了console.log()语句 不幸的是,现在闭包编译器正在删除我的全部代码,而不仅仅是console.log()语句 有人能解释一下吗?我不知所措 JS文件1 (function(){ /** @const */ LOG = false; function log() { return console.log.apply(console, arguments); } LOG && log('hello world !'); var foo='b

我已经从代码中删除了
console.log()
语句

不幸的是,现在闭包编译器正在删除我的全部代码,而不仅仅是
console.log()
语句

有人能解释一下吗?我不知所措

JS文件1

(function(){
/** @const */
LOG = false;

function log() {
    return console.log.apply(console, arguments);
}

LOG && log('hello world !');

var foo='bar';
LOG && log("foo"+foo);
})();
/** @const */
var LOG = false;

function log() {
    return console.log.apply(console, arguments);
}

LOG && log('hello world !');

var foo='bar';
LOG && log("foo"+foo);
JS文件2

(function(){
/** @const */
LOG = false;    

function test(){
    alert('testing...');
}

var baz='bazzy';
LOG && log("baz"+baz);


})();
function test(){
    alert('testing...');
}

var baz='bazzy';
LOG && log("baz"+baz);

// call test, so it a) isnt stripped and b) well, executed :)
test();
闭包编译器步骤:

$ java -jar compiler-latest/compiler.jar --js j1.js j2.js --js_output_file compiled.js 
(function(){LOG=!1})();(function(){LOG=!1})();
结果:

$ java -jar compiler-latest/compiler.jar --js j1.js j2.js --js_output_file compiled.js 
(function(){LOG=!1})();(function(){LOG=!1})();

因为编译器确定代码的其余部分无法访问

这两个文件的常量日志都设置为false,并且您没有导出任何内容(goog.export*或window['.']=…)。 可能被执行的代码前面有一个日志&,这意味着它没有被执行

因此,无法执行任何操作,因此编译器会将其全部删除

为什么要删除函数测试:没有人调用它,就这么简单。在您的一个文件中调用它,编译器不会将其删除


您可以(实际上应该)在一个文件中定义日志和日志。 为此,请删除每个文件中围绕代码的匿名函数调用。 您可以告诉编译器使用命令行选项将其添加回已编译代码:

--output_wrapper=(function(){ %output% })();
因此,您的两个文件应如下所示:

JS文件1

(function(){
/** @const */
LOG = false;

function log() {
    return console.log.apply(console, arguments);
}

LOG && log('hello world !');

var foo='bar';
LOG && log("foo"+foo);
})();
/** @const */
var LOG = false;

function log() {
    return console.log.apply(console, arguments);
}

LOG && log('hello world !');

var foo='bar';
LOG && log("foo"+foo);
JS文件2

(function(){
/** @const */
LOG = false;    

function test(){
    alert('testing...');
}

var baz='bazzy';
LOG && log("baz"+baz);


})();
function test(){
    alert('testing...');
}

var baz='bazzy';
LOG && log("baz"+baz);

// call test, so it a) isnt stripped and b) well, executed :)
test();
此外,您可能希望将全局变量和函数放入“命名空间”中,以避免污染全局范围:

// create namespace (which is just a normal object)
var MyNamespace = {};

// create a namespaced function
MyNamespace.test = function() {
    alert('test');
}

// call it
MyNamespace.test();

所以为了保持
test()
我需要将它声明为
window['test']
?对于其他全局变量也是一样的?如果您希望导出该变量,也就是说可以从其他未编译的代码中调用,那么可以。但为了实现这一点,请使用goog.exportSymbol()(其实并不重要,但如果其他人阅读了代码,则会使意图更加清晰)。我的所有代码都将编译到一个文件中,不需要被其他未编译的代码调用。我假设在每个文件中定义
LOG
也是错误的。你介意包括你的答案吗?根据这个,这两个简单的JS文件应该如何更改?顺便说一句,如果我将其更改为
window['test']=function(){…
然后下面的console.log代码不再被删除。令人困惑。@Timperson刚刚编辑了我的答案,因为只有一个文件上有日志删除
log
调用时留下的其余代码没有任何作用,所以它也被删除了…我如何保留测试()函数?该函数是本地定义的,从未调用过。请更改其中一个。@Bergi将其更改为
window['test']=function(){…
,然后防止删除它下面的log()语句。