精华 UglifyJs 批量压缩脚本福利
发布于 2个月前 作者 tulayang 458 次浏览 来自 分享

最近写了个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);
    }
});

使用

  1. 修改脚本,设置source源目录,target目标目录

    目标目录必须是未建立的目录 .js文件必须是合法的js语法文件

  2. $ node build.js

1 回复

为什么不用GRUNT呢?

回到顶部