gulpfile.js 6.86 KB
/**
 * GULP-FILE
 * author: xuqi(qi.xu@yoho.cn)
 * date: 2015/9/30
 */

var gulp = require('gulp'),
    cp = require('child_process');

var fs = require('fs'),
    ftp = require('gulp-ftp'),
    gutil = require('gulp-util'),
    uglify = require('gulp-uglify'),
    Package = require('father').SpmPackage,
    transport = require('gulp-spm'),
    concat = require('gulp-concat');

var postcss = require('gulp-postcss');
var sourcemaps = require('gulp-sourcemaps');
var cssnano = require('gulp-cssnano');

var config = require('./package');

var rootDist = 'dist/myohobuy/',
    ftpConfig = {
        host: '218.94.75.58',
        user: 'php',
        pass: 'yoho9646'
    };

var distDir = {
    js: rootDist + config.version,
    css: rootDist + config.version,
    img: rootDist + 'assets/img',
    font: rootDist + 'assets/font'
};

gulp.task('default', ['postcss-dev', 'postcss-watch', 'spm-doc']);


//根据环境变量生成postcss插件配置
function postcssEnvPlugin(env) {
    var sprites = {
        spritesmith: {
            padding: 4
        },
        groupBy: function(file) {

            // 根据目录分组,防止合并后的图片太大
            var group = file.url.split('/')[1];

            file.retina = true; // H5 强制所有图片都是用二倍图
            return group ? Promise.resolve(group) : Promise.reject();
        },
        filterBy: function(file) {

            //使用resolve转化后静态资源生成../img或者../assets/img/的路径
            if (/\/img/.test(file.url) || /data:image/.test(file.url)) {
                return Promise.reject();
            }
            return Promise.resolve();
        }
    },
    assets;

    if (env === 'DEV') {
        assets = {
            loadPaths: ['font/', 'img/'],
            relativeTo: 'css/'
        };

        Object.assign(sprites, {
            basePath: './img',
            stylesheetPath: './css',
            spritePath: './img'
        });
    } else if (env === 'PRO') {
        assets = {
            loadPaths: [distDir.img, distDir.font],
            relativeTo: distDir.css,
            cachebuster: function(filePath, urlPathname) {

                //只给字体加no-cache
                if (/font\//.test(urlPathname)) {
                    return fs.statSync(filePath).mtime.getTime().toString(16);
                }
            }
        };

        Object.assign(sprites, {
            basePath: distDir.img,
            stylesheetPath: distDir.css,
            spritePath: distDir.img
        });
    }

    return [
        require('precss'),
        require('postcss-assets')(assets),
        require('postcss-sprites').default(sprites),
        require('postcss-calc'),
        require('postcss-pxtorem')({
            rootValue: 40,
            unitPrecision: 5, // 保留5位小数字
            minPixelValue: 2, // 小于 2px 时,不转换, 单位为 PX 大写的时候不转换
            selectorBlackList: [], // 选择器黑名单,可以使用正则
            propWhiteList: [] // 属性名称为空,表示替换所有属性的值
        }),
        require('autoprefixer')({
            add: true,
            browsers: ['> 1%']
        }),

        //可选
        require('postcss-use')({
            modules: ['postcss-clearfix', 'postcss-crip', 'postcss-short', 'postcss-center', 'postcss-position']
        })
    ];
}

//Postcss开发环境
gulp.task('postcss-dev', function() {
    return gulp.src('sass/index.css')
        .pipe(sourcemaps.init())
        .pipe(postcss(postcssEnvPlugin('DEV')))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('css/'))
});

gulp.task('postcss-watch', function() {
    gulp.watch('sass/**/*.css', ['postcss-dev']);
});

//Postcss正式环境生成
gulp.task('postcss-pro', ['assets'], function() {
    return gulp.src('sass/index.css')
        .pipe(postcss(postcssEnvPlugin('PRO')))
        .pipe(cssnano())
        .pipe(gulp.dest(distDir.css))
});

// start spm server
gulp.task('spm-doc', function() {
    var sd = cp.exec('spm doc watch --port 8000'); // PC 用8001,H5 用8000, 跑两个服务器,不冲突

    // sd.stdout.on('data', function(data) {
    //     console.log(data);
    // });

    sd.stderr.on('data', function(data) {
        console.log(data);
    });

    sd.on('exit', function(code) {
        console.log('process spm doc exit with code ' + code);
    });
});

//生成发布目录,可用于上传测试机
gulp.task('ge', ['assets', 'postcss-pro', 'build']);

//发布
gulp.task('dist', ['assets', 'postcss-pro', 'build'], function() {
    var ftpstream = ftp(ftpConfig);

    return gulp.src('dist/**/')
        .pipe(ftpstream)
        .pipe(gutil.noop());
});

//font+img->dist/assets
gulp.task('assets', ['img', 'font']);

gulp.task('img', function() {
    return gulp.src('img/**/*')
        .pipe(gulp.dest(distDir.img));
});

gulp.task('font', function() {
    return gulp.src('font/*')
        .pipe(gulp.dest(distDir.font))
});

//spm build
gulp.task('build', ['libs', 'business']);

//libs
gulp.task('libs', ['pre-libs', 'concat-min-libs', 'clear-libs']);

gulp.task('pre-libs', function() {
    var obj = {
        name: '',
        version: config.version,
        spm: config.spm
    };
    var packages = [],
        libsjs = '';

    var libCon, key, i;

    var pkg;

    obj.spm.main = 'libs.js';
    obj.spm.buildArgs = '--idleading {{}} --include all';

    libCon = JSON.stringify(obj);

    fs.renameSync('package.json', 'package.bak.json');
    fs.writeFileSync('package.json', libCon);

    for (key in obj.spm.dependencies) {
        if (obj.spm.inside && obj.spm.inside[key]) {
            packages.push(obj.spm.inside[key]);
        } else {
            packages.push(key);
        }
    }

    for (i = 0; i < packages.length; i++) {
        libsjs += 'require("' + packages[i] + '");';
    }

    fs.writeFileSync('libs.js', libsjs); //重写入口文件

    pkg = new Package(__dirname);

    return gulp.src(pkg.main)
        .pipe(transport({
            pkg: pkg
        }))
        .pipe(gulp.dest(distDir.js));
});

gulp.task('concat-min-libs', ['pre-libs'], function() {
    var path = distDir.js + '/libs.js';
    var jsStr = fs.readFileSync(path).toString();

    fs.writeFileSync(path, jsStr.substr(jsStr.indexOf('});') + 4));

    return gulp.src(['plugin/sea.js', distDir.js + '/libs.js'])
        .pipe(concat('lib.js'))
        .pipe(uglify())
        .pipe(gulp.dest(distDir.js));
});

gulp.task('clear-libs', ['concat-min-libs'], function() {
    fs.renameSync('package.bak.json', 'package.json');
    fs.unlinkSync('./libs.js');
    fs.unlinkSync(distDir.js + '/libs.js');
});

gulp.task('business', ['libs'], function() {
    var pkg = new Package(__dirname);

    return gulp.src(pkg.main)
        .pipe(transport({
            pkg: pkg
        }))
        .pipe(concat('index-debug.js'))
        .pipe(gulp.dest(distDir.js))
        .pipe(uglify())
        .pipe(concat('index.js'))
        .pipe(gulp.dest(distDir.js));
});