smallnewer / bugs

18 stars 4 forks source link

资源管理,上线前需要整体跑一边---Gulp的应用 #61

Open zhkuang opened 9 years ago

zhkuang commented 9 years ago

主要依赖几个模块:

var fs = require('fs');
var Path = require("path");

var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat'); // 代码拼接
var uglify = require('gulp-uglify'); // 代码压缩
var rename = require('gulp-rename'); // 重命名
var rev = require('gulp-rev'); // 修改版本号, 生成map json

var imagemin = require('gulp-imagemin'); // 压缩图片
var pngquant = require('imagemin-pngquant'); // 深度压缩png
var cache = require('gulp-cache'); // 主要用于缓存已经压缩过的图片,每次只压缩新更新的

var manifest = require('gulp-manifest'); // 生成manifest

执行流


// 语法检查(有时间再用)
gulp.task('jshint', function() {
    return gulp.src('src/**/*.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'));
});

// 合并、压缩代码
gulp.task('minify', function() {
    return gulp.src(arr)
        .pipe(concat('all.js'))
        .pipe(gulp.dest('dist'))
        .pipe(uglify())
        .pipe(rename('all.min.js'))
        .pipe(gulp.dest('dist'));
});

// 文件重命名(md5)生成 map json
gulp.task("rmd5", function() {
    return gulp.src("res/**")
        .pipe(rev())
        .pipe(gulp.dest('dist/assets'))
        .pipe(rev.manifest())
        .pipe(gulp.dest('dist/assets'));
});

// 修改拼图json中对png文件名的依赖以及骨骼动画中atlas和png文件
gulp.task("modify", ['rmd5'], function() {
    // 1. json + atlas + png 名称以json统一
    // 2. atlas 修改其中 png名称
    // 3. json + png 修改json中png名称

    var urls = [];
    var modifyed = [];

    function parsePath(path) {
        var extname = Path.extname(path);
        return {
            dirname: Path.dirname(path),
            basename: Path.basename(path, extname),
            extname: extname
        };
    }

    function map(ff) {
        var files = fs.readdirSync(ff);
        for (fn in files) {
            var fname = ff + Path.sep + files[fn];
            var stat = fs.lstatSync(fname);
            if (stat.isDirectory() == true) {
                map(fname);
            } else {
                urls.push(parsePath(fname));
            }
        }
    }

    map("dist/");

    for (var i = 0; i < urls.length; i++) {
        modify(urls[i]);
    }

    function modify(path) {

        if (path.basename == '' || path.extname == '')
            return;

        if (path.basename.indexOf("sheet-") < 0)
            return;

        var dirpath = path.dirname;
        for (var i = 0; i < modifyed.length; i++) { // 已经修改过的目录就不改了,所以一个目录只能放一套
            if (dirpath == modifyed[i]) {
                return;
            }
        }

        var files = fs.readdirSync(dirpath);
        if (files && files.length) {

            var hasjson = false,
                hasatlas = false,
                haspng = false;

            for (var i = 0; i < files.length; i++) {
                var filename = files[i];

                if (filename.indexOf("sheet-") < 0)
                    continue;

                if (filename.indexOf(".json") != -1) {
                    hasjson = true;
                } else if (filename.indexOf(".atlas") != -1) {
                    hasatlas = true;
                } else if (filename.indexOf(".png") != -1) {
                    haspng = true;
                }
            }

            if (hasjson && haspng && !hasatlas) { // 拼图目录
                modifyHash();
                modifyed.push(dirpath);
            } else if (hasjson && haspng && hasatlas) { // 骨骼目录
                modifyBone();
                modifyed.push(dirpath);
            }
        }

        function modifyBone() { // 修改骨骼中的atlas和png,名称统一为json名称,顺便修改atlas中png名称
            // 筛选出json的文件名
            var jsonfile = null;
            for (var i = 0; i < files.length; i++) {
                var filename = files[i];
                if (filename.indexOf("sheet-") < 0)
                    continue;

                if (filename.indexOf(".json") != -1) {
                    jsonfile = filename.split(".")[0];
                    break;
                }
            }

            if (!jsonfile) {
                console.error(dirpath + "  没有找到json文件");
                return;
            }

            for (var i = 0; i < files.length; i++) {
                var filename = files[i];
                if (filename.indexOf("sheet-") < 0)
                    continue;

                var filepath = dirpath + "/" + filename;
                // === 修改atlas文件名 ===
                if (filename.indexOf(".atlas") != -1) {
                    var newpath = dirpath + "/" + jsonfile + ".atlas";

                    // 修改对png的引用
                    var str = fs.readFileSync(filepath);
                    var bstr = str.toString();
                    if (bstr.indexOf('sheet.png') != -1) {
                        var arr = bstr.split("sheet.png");

                        // 防止文件中还存在别的sheet.png字段
                        if (arr.length != 2) {
                            console.warn("atlas中出现了两个sheet.png");
                        }

                        // 替换sheet.png为新的
                        arr.splice(0, 1, jsonfile + ".png");
                        fs.writeFileSync(newpath, arr.join(""));
                    }

                }

                // === 修改png 文件名 ===
                if (filename.indexOf(".png") != -1) {
                    var newpath = dirpath + "/" + jsonfile + ".png";
                    fs.rename(filepath, newpath);
                }

            }
        }

        function modifyHash() { // 修改拼图json中的png名称

            // 筛选出png的文件名
            var pngfile = null;
            for (var i = 0; i < files.length; i++) {
                var filename = files[i];
                if (filename.indexOf("sheet-") < 0)
                    continue;

                if (filename.indexOf(".png") != -1) {
                    pngfile = filename;
                    break;
                }
            }

            if (!pngfile) {
                console.error(dirpath + "  没有找到png文件");
                return;
            }

            // 修改对应json 中的png文件名引用
            for (var i = 0; i < files.length; i++) {
                var filename = files[i];
                if (filename.indexOf("sheet-") < 0)
                    continue;

                if (filename.indexOf(".json") != -1) {
                    // 修改对png的引用
                    var newpath = dirpath + "/" + filename;
                    var str = fs.readFileSync(newpath);
                    var bstr = str.toString();
                    if (bstr.indexOf('"image": "sheet.png"') != -1) {
                        var arr = bstr.split('"image": "sheet.png"');

                        if (arr.length != 2) {
                            console.warn(arr.length);
                        }

                        // 替换sheet.png为新的
                        fs.writeFileSync(newpath, arr.join('"image": "' + pngfile + '"'));
                    }
                }

            }
        }
    }

});

// 生成mainfest
gulp.task('manifest', function() {
    return gulp.src(['dist/assets/**'])
        .pipe(manifest({
            hash: true,                                 // 根据文件内容生成hash,保证有更新后下载新的manifest
            timestamp: true,                            // 跟上面的作用差不多,一个时间戳
            preferOnline: true,                         // 优先加载线上的
            network: ['http://*', 'https://*', '*'],
            filename: 'app.manifest',
            exclude: 'app.manifest'
        }))
        .pipe(gulp.dest('dist/test'));
});

// 图片的资源的压缩处理
// gulp.task("imgcompress", function () {
//     return gulp.src('dist/assets/test.png')
//         .pipe(imagemin({
//             progressive: true,                              // 无损压缩jpg图片
//             optimizationLevel: 1,                          // 取值范围:0-7(优化等级)
//             use: [pngquant()]                               // 使用pngquant深度压缩png图片的imagemin插件
//         }))
//         .pipe(gulp.dest('dist/test'));
// });

// == 清楚缓存 ===
// gulp.task('clear', function (done) {
//   return cache.clearAll(done);
// });