UNPKG

dojo-util

Version:

Dojo utilities including build system for optimizing JavaScript application performance, and DOH testing tool

157 lines (151 loc) 5.48 kB
/*jshint node:true */ define([ "../../buildControl", "../../fileUtils", "dojo/has" ], function(bc, fileUtils, has){ // start up a few processes to compensate for the miserably slow closure compiler var processes = [], killAllRunners = function(){ processes.forEach(function(proc){ try{ proc.runner && proc.runner.kill(); proc.runner = 0; }catch(e){ //squelch } }); }; // don't leave orphan child procs global.process.on("exit", killAllRunners); global.process.on("uncaughtException", function(err){ killAllRunners(); // TODO: log these via bc.log console.log(err); console.log(err.stack); global.process.exit(-1); }); if(bc.maxOptimizationProcesses < 0){ bc.maxOptimizationProcesses = require.nodeRequire('os').cpus().length; } var processesStarted = 0, totalOptimizerOutput = "", nextProcId = 0, i, //used in for loop sendJob = function(src, dest, optimizeSwitch, copyright){ processes[nextProcId++].write(src, dest, optimizeSwitch, copyright); nextProcId= nextProcId % bc.maxOptimizationProcesses; }, doneRe = new RegExp("^Done\\s\\(compile\\stime.+$", "m"), optimizerRunner = require.toUrl("build/optimizeRunner.js"), buildRoot = optimizerRunner.match(/(.+)\/build\/optimizeRunner\.js$/)[1], runJava, //function, defined later oldSendJob = sendJob, //preserves reference if sendJob is replaced child_process = require.nodeRequire("child_process"), isCygwin = global.process.platform === 'cygwin', separator = has("is-windows") ? ";" : ":", javaClasses = fileUtils.catPath(buildRoot, "closureCompiler/compiler.jar") + separator + fileUtils.catPath(buildRoot, "shrinksafe/js.jar") + separator + fileUtils.catPath(buildRoot, "shrinksafe/shrinksafe.jar"); if(isCygwin){ //assume we're working with Windows Java, and need to translate paths runJava = function(cb){ child_process.exec("cygpath -wp '" + javaClasses + "'", function(err, stdout){ javaClasses = stdout.trim(); child_process.exec("cygpath -w '" + optimizerRunner + "'", function(err, stdout){ optimizerRunner = stdout.trim(); cb(); }); }); }; //wrap sendJob calls to convert to windows paths first sendJob = function(src, dest, optimizeSwitch, copyright){ child_process.exec("cygpath -wp '" + src + "'", function(err, srcstdout){ child_process.exec("cygpath -wp '" + dest + "'", function(err, deststdout){ oldSendJob(srcstdout.trim(), deststdout.trim(), optimizeSwitch, copyright); }); }); }; }else if(has("is-windows")){ runJava = function(cb){ javaClasses = fileUtils.normalize(javaClasses); optimizerRunner = fileUtils.normalize(optimizerRunner); cb(); }; sendJob = function(src, dest, optimizeSwitch, copyright){ var wsrc = fileUtils.normalize(src); var wdest = fileUtils.normalize(dest); oldSendJob(wsrc, wdest, optimizeSwitch, copyright); }; }else{ //no waiting necessary, pass through runJava = function(cb) { cb(); }; } runJava(function() { for(i = 0; i < bc.maxOptimizationProcesses; i++) {(function(){ var runner = child_process.spawn("java", ["-cp", javaClasses, "org.mozilla.javascript.tools.shell.Main", optimizerRunner]), proc = { runner:runner, results:"", tempResults:"", sent:[], write:function(src, dest, optimizeSwitch, copyright){ proc.sent.push(dest); runner.stdin.write(src + "\n" + dest + "\n" + optimizeSwitch + "\n" + JSON.stringify({ copyright: copyright, options: bc.optimizeOptions, useSourceMaps: bc.useSourceMaps }) + "\n"); }, sink:function(output){ proc.tempResults += output; var match, message, chunkLength; while((match = proc.tempResults.match(doneRe))){ message = match[0]; if(/OPTIMIZER\sFAILED/.test(message)){ bc.log("optimizeFailed", ["module identifier", proc.sent.shift(), "exception", message.substring(5)]); }else{ bc.log("optimizeDone", [proc.sent.shift() + " " + message.substring(5)]); } chunkLength = match.index + message.length; proc.results += proc.tempResults.substring(0, chunkLength); proc.tempResults = proc.tempResults.substring(chunkLength); } } }; processesStarted++; // matches *3* runner.stdout.on("data", function(data){ // the +"" converts to Javascript string proc.sink(data + ""); }), runner.stderr.on("data", function(data){ // the +"" converts to Javascript string proc.sink(data + ""); }), runner.on("exit", function(){ proc.results += proc.tempResults; totalOptimizerOutput += proc.results; bc.logOptimizerOutput(totalOptimizerOutput); processesStarted--; // matches *3* if(!processesStarted){ // all the processes have completed and shut down at this point if(bc.showOptimizerOutput){ bc.log("optimizeMessages", [totalOptimizerOutput]); } bc.passGate(); // matched with *1* } }); processes.push(proc); })();} }); //end runJava(function...) bc.gateListeners.push(function(gate){ if(gate==="cleanup"){ // going through the cleanup gate signals that all optimizations have been started; // we now signal the runner there are no more files and wait for the runner to stop bc.log("pacify", "waiting for the optimizer runner to finish..."); bc.waiting++; // matched with *1* processes.forEach(function(proc){ proc.write(".\n"); }); processes = []; } }); return sendJob; });