在缩小过程中排除debuggingJavaScript代码

我正在寻找不同的方法来缩小我的JavaScript代码,包括常规的JSMin ,Packer和YUI解决scheme。 我对新的Google Closure编译器非常感兴趣,因为它看起来非常强大。

我注意到Dean Edwards打包器有一个function,可以排除以三个分号开始的代码行。 这是排除debugging代码的方便。 例如:

;;; console.log("Starting process"); 

我花了一些时间清理我的代码库,并希望添加这样的提示,以轻松排除debugging代码。 在准备这个,我想弄清楚这是最好的解决scheme,还是有其他的技术。

因为我还没有select如何缩小,所以我想用一种与最终结果一致的方式来清理代码。 所以我的问题是这样的:

  1. 使用分号是一种标准的技术,还是有其他的方法来做到这一点?

  2. Packer是唯一提供此function的解决scheme吗?

  3. 其他解决scheme是否也可以适应这种方式工作,还是有其他方法来完成这个工作?

  4. 我可能会最终开始使用Closure编译器。 有什么我现在应该做的准备呢?

这里是闭包编译器的(最终)答案:

 /** @const */ var LOG = false; ... LOG && log('hello world !'); // compiler will remove this line ... 

这甚至可以和SIMPLE_OPTIMIZATIONS配合SIMPLE_OPTIMIZATIONS ,而不需要--define=

这是我用Closure编译器。 首先,你需要定义一个像这样的DEBUGvariables:

 /** @define {boolean} */ var DEBUG = true; 

它使用JS注释来closures,你可以在文档中看到 。

现在,只要你想要一些只能debugging的代码,就把它包装在if语句中,如下所示:

 if (DEBUG) { console.log("Running in DEBUG mode"); } 

编译你的代码发布时,添加下面的编译命令:– --define='DEBUG=false' – debugging语句中的任何代码将被完全排除在编译的文件之外。

在这种情况下,一个好的解决scheme可能是支持“条件编译”的js-build-tools 。

总之你可以使用评论如

 // #ifdef debug var trace = debug.getTracer("easyXDM.Rpc"); trace("constructor"); // #endif 

在那里你定义一个编译指示,如debug

然后当它build立(它有一个ant任务)

 //this file will not have the debug code <preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.js"/> //this file will <preprocess infile="work/easyXDM.combined.js" outfile="work/easyXDM.debug.js" defines="debug"/> 

如果你在高级模式下使用闭包编译器,你可以这样做:

 if (DEBUG) console.log = function() {} 

然后编译器会删除所有的console.log调用。 当然你需要在命令行中--definevariablesDEBUG

但是,这只适用于高级模式 。 如果您使用简单模式,则需要在源文件上运行预处理器。

为什么不考虑Dojo工具包? 它内置了基于注释的编译指示来包含/排除基于构build的代码段。 此外,它与高级模式下的Closure编译器兼容(请参阅下面的链接)!

http://dojo-toolkit.33424.n3.nabble.com/file/n2636749/Using_the_Dojo_Toolkit_with_the_Closure_Compiler.pdf?by-user=t

尽pipe它是一个老问题。 今天我偶然发现了同样的问题,发现它可以使用CompilerOptions来实现。

我跟着这个线程 。

在将代码发送到客户端之前,我们在服务器上运行Java的编译器。 这在简单模式下适用于我们。

 private String compressWithClosureCompiler(final String code) { final Compiler compiler = new Compiler(); final CompilerOptions options = new CompilerOptions(); Logger.getLogger("com.google.javascript.jscomp").setLevel(Level.OFF); if (compressRemovesLogging) { options.stripNamePrefixes = ImmutableSet.of("logger"); options.stripNameSuffixes = ImmutableSet.of("debug", "dev", "info", "error", "warn", "startClock", "stopClock", "dir"); } CompilationLevel.SIMPLE_OPTIMIZATIONS.setOptionsForCompilationLevel(options); final JSSourceFile extern = JSSourceFile.fromCode("externs.js", ""); final JSSourceFile input = JSSourceFile.fromCode("input.js", code); compiler.compile(extern, input, options); return compiler.toSource(); } 

它将删除所有对logger.debug,logger.dev等等的调用

将代码添加到代码中login到控制台的每个位置,都会使debugging和维护变得更加困难。

如果您已经为生产代码添加构build步骤,则可以在顶部添加另一个文件,将您的console方法变为noop

就像是:

 console.log = console.debug = console.info = function(){}; 

理想情况下,你只需要去除任何console方法,但是如果你保留它们,但不使用它们,这可能是最简单的方法。

如果您使用的是UglifyJS2 ,则可以使用drop_console参数来移除控制台。*函数。

我与@ marcel-korpel。 不完美,但工程。 缩小前请更换debugging指令。 正则expression式在许多地方起作用。 注意未封闭的线路。

 /console\.[^;]*/gm 

适用于:

 ;;; console.log("Starting process"); console.log("Starting process"); console.dir("Starting process");;;;; console.log("Starting "+(1+2)+" processes"); iamok('good'); console.log('Message ' + 'with new line' ); console.group("a"); console.groupEnd(); swtich(input){ case 1 : alert('ok'); break; default: console.warn("Fatal error"); break; } 

不要工作:

 console.log("instruction without semicolon") console.log("semicolon in ; string"); 

到目前为止,我还没有研究过缩小,但是这种行为可以使用一个简单的正则expression式来完成:

 s/;;;.*//g 

这样在一行之后(并且包括)三个分号replace掉所有内容,所以在缩小前丢弃。 在运行缩小工具之前,您可以运行sed (或类似的工具),如下所示:

 sed 's/;;;.*//g' < infile.js > outfile.js 

顺便说一句,如果你想知道压缩版本还是压缩版本会更好,请阅读JavaScript压缩方法的比较 。

我已经使用了以下自制stuf:

 // Uncomment to enable debug messages // var debug = true; function ShowDebugMessage(message) { if (debug) { alert(message); } } 

所以当你声明variablesdebug被设置为true ,所有的ShowDebugMessage()调用都会调用alert() 。 因此,只需在代码中使用它,并忘记debugging输出行的ifdef或手动注释等条件。