最近写了个UglifyJs批处理压缩脚本,既然有nodejs,我们当然用不到笨手笨脚的Shell了. 使用此前提出的"尾递归"readSync(paths, i)的修订版readSync(paths, i, f);
场景是这样: 面对一个项目,充满了不止’.js’文件,还有’.jpg’, '.mpg’. 希望复制这些文件,而压缩’.js’文件,并生成一个与源项目层次一样的副本.
app
|-server.js
|-public
|-a.img
=>
newapp
|-server.js
|-public
|-a.img
源代码
// build.js
var UGLIFYJS = require('uglify-js');
var FS = require('fs');
var PATH = require('path');
function readSync(paths, i, f) {
if (i >= 0 && i < paths.length) {
var stats = FS.statSync(paths[i]);
if (stats.isFile()) {
f('file', paths[i]);
return readSync(paths, ++i, f);
} else if (stats.isDirectory()) {
var newPaths = FS.readdirSync(paths[i]).map(function (path) {
return PATH.join(paths[i], path);
});
f('directory', paths[i]);
return readSync(paths.slice(0, i).concat(newPaths,
paths.slice(i + 1)),
i, f);
} else {
return readSync(paths.slice(0, i).concat(paths.slice(i + 1)),
i, f);
}
} else {
return paths;
}
}
var source = '/home/king/project/app',
target = '/home/king/project/to';
readSync([source], 0, function (type, path) {
var newPath = PATH.join(target, path.replace(new RegExp('^' + source.replace(/\//g,'\/').replace(/\\/g,'\\')), ''));
if (type === 'file') {
if (PATH.extname(path) !== '.js') {
console.log('copy %s %s', path, newPath);
FS.writeFileSync(newPath, FS.readFileSync(path));
return;
}
var ast = UGLIFYJS.parse(UGLIFYJS.minify(path).code, {
strict: false
});
ast.figure_out_scope();
var com = ast.transform(UGLIFYJS.Compressor({}));
com.figure_out_scope();
com.compute_char_frequency();
com.mangle_names();
console.log('ug %s %s', path, newPath);
FS.writeFileSync(newPath, com.print_to_string(), {encoding:'utf8'});
}
if (type === 'directory') {
console.log('mkdir %s', newPath);
FS.mkdirSync(newPath);
}
});
使用
-
修改脚本,设置source源目录,target目标目录
目标目录必须是未建立的目录 .js文件必须是合法的js语法文件
-
$ node build.js