Skip to content

Instantly share code, notes, and snippets.

@makeusabrew
Created October 25, 2011 11:54
Show Gist options
  • Save makeusabrew/1312457 to your computer and use it in GitHub Desktop.
Save makeusabrew/1312457 to your computer and use it in GitHub Desktop.
Watch a specified directory's JavaScript files and recompile a specified output file if any changes are detected
/**
* Sample usage - note that the trailing slash on the watch directory is important!
*
* node uglify.js /path/to/my/src/directory/ /path/to/my/output/file.js
*/
var jsp = require('uglify-js').parser,
pro = require('uglify-js').uglify,
fs = require('fs');
// take the directory to watch...
var srcDir = process.argv[2];
// ... and the destination file as command line arguments
var destFile = process.argv[3];
// grab the files to watch...
var sourceFiles = fs.readdirSync(srcDir);
// keep a cache of compiled files so we don't have to recompile all of them every time
var compressedFiles = {};
var compile = function(file, cb) {
var code = fs.readFileSync(file, "utf8");
if (compressedFiles[file] == null) {
console.log("compressing "+file);
} else {
console.log("re-compressing "+file);
}
// lifted from https://github.com/mishoo/UglifyJS
var ast = jsp.parse(code); // parse code and get the initial AST
ast = pro.ast_mangle(ast); // get a new AST with mangled names
ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
var final_code = pro.gen_code(ast); // compressed code here
// cache the compressed version of this file
compressedFiles[file] = final_code;
// if we've got a callback, assume it wants the output of all our files
if (typeof cb == 'function') {
var output = "";
for (var i in compressedFiles) {
output += compressedFiles[i]+";";
}
cb(output);
}
}
/**
* Go!
*/
sourceFiles.forEach(function(file) {
if (file.match(/\.js$/)) {
var fullPath = srcDir+file;
compile(fullPath);
fs.watchFile(fullPath, function(curr, prev) {
if (curr.mtime > prev.mtime) {
console.log(file+" modified!");
compile(fullPath, function(output) {
fs.writeFile(destFile, output, function(err) {
if (err) throw err;
console.log("written file to "+destFile);
});
});
} else {
console.log(file+" accessed...");
}
});
}
});
nick@nick-desktop:~/www/foo/node$ node uglify.js ~/www/foo/src/js/ ~/www/foo/public/js/run.js
compressing /home/nick/www/foo/src/js/client.js
compressing /home/nick/www/foo/src/js/bullet.js
compressing /home/nick/www/foo/src/js/surface.js
compressing /home/nick/www/foo/src/js/input.js
compressing /home/nick/www/foo/src/js/message_box.js
client.js accessed...
client.js modified!
re-compressing /home/nick/www/foo/src/js/client.js
written file to /home/nick/www/foo/public/js/run.js
@joshnesbitt
Copy link

Nice idea. I started something like that for a contracting gig a while back with @JamieMason with testing a bunch of files using Guard. Also wrote Processr which helps manipulate text with filters etc. It's not Node, but I'm tempted by it with the amount of JS I'm writing lately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment