在缩小过程中排除debuggingJavaScript代码
我正在寻找不同的方法来缩小我的JavaScript代码,包括常规的JSMin ,Packer和YUI解决scheme。 我对新的Google Closure编译器非常感兴趣,因为它看起来非常强大。
我注意到Dean Edwards打包器有一个function,可以排除以三个分号开始的代码行。 这是排除debugging代码的方便。 例如:
;;; console.log("Starting process");
我花了一些时间清理我的代码库,并希望添加这样的提示,以轻松排除debugging代码。 在准备这个,我想弄清楚这是最好的解决scheme,还是有其他的技术。
因为我还没有select如何缩小,所以我想用一种与最终结果一致的方式来清理代码。 所以我的问题是这样的:
-
使用分号是一种标准的技术,还是有其他的方法来做到这一点?
-
Packer是唯一提供此function的解决scheme吗?
-
其他解决scheme是否也可以适应这种方式工作,还是有其他方法来完成这个工作?
-
我可能会最终开始使用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调用。 当然你需要在命令行中--define
variablesDEBUG
。
但是,这只适用于高级模式 。 如果您使用简单模式,则需要在源文件上运行预处理器。
为什么不考虑Dojo工具包? 它内置了基于注释的编译指示来包含/排除基于构build的代码段。 此外,它与高级模式下的Closure编译器兼容(请参阅下面的链接)!
尽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
或手动注释等条件。