gulpfile.js 4.8 KB
/**
 * Yo构建脚本
 * @author: xuqi<qi.xu@yoho.cn>
 * @date: 2016/4/20
 */

'use strict';

const fs = require('fs');

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

const env = {
    dev: Symbol('development'),
    pro: Symbol('production')
};

// config
const config = require('./package.json');
const rootdir = `dist/${config.name}`;
const ftpConfig = {
    host: '218.94.75.58',
    user: 'php',
    pass: 'yoho9646'
};
const dist = {
    js: `${rootdir}/${config.version}`,
    css: `${rootdir}/${config.version}`,
    img: `${rootdir}/assets/img`,
    font: `${rootdir}/assets/font`
};

/**
 * postcss plugins for both dev and pro
 * @parem et Symbol
 * @param module String 模块名
 */
const postcssPlugin = (et, module) => {
    var sprites = {
        spritesmith: {
            padding: 2
        },
        groupBy(file) {
            var group = file.url.split('/')[0];

            group = group === '' ? 'yo' : group;

            return group ? Promise.resolve(group) : Promise.reject(group);
        }
    },
    assets,
    plugins;

    // assets & sprites config in both dev and pro
    if (et === env.pro) {
        assets = {
            loadPaths: [dist.img, dist.font],
            relativeTo: `${dist.css}/${module}`
        };

        Object.assign(sprites, {
            basePath: dist.img,
            stylesheetPath: `${dist.css}/${module}`,
            spritePath: dist.img
        });
    } else if (et === env.dev) {
        assets = {
            loadPaths: ['static/assets/font/', 'static/assets/img/'],
            relativeTo: `static/module/${module}/css`
        };

        Object.assign(sprites, {
            basePath: 'static/assets/img/',
            stylesheetPath: `static/module/${module}/css`,
            spritePath: 'static/assets/img/'
        });
    };

    plugins = [
        require('autoprefixer')({
            browsers: ['> 1%']
        }),
        require('precss'),
        require('postcss-sprites').default(sprites),
        require('postcss-assets')(assets),
        require('postcss-calc'),
        require('postcss-opacity'),

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

    if (et === env.pro) {
        plugins.push(require('postcss-cachebuster')({
            imagesPath: `/${dist.img}`,
            cssPath: `/${dist.css}/${module}`
        }));
    }
    return plugins;
};

/**
 * 模块下CSS编译
 * @param module String 模块名
 * @param et Symbol 环境
 */
const compileForModule = (module, et) => {
    if (et === env.dev) {
        return gulp.src(`static/module/${module}/scss/index.css`)
                .pipe(sourcemaps.init())
                .pipe(postcss(postcssPlugin(et, module)))
                .pipe(sourcemaps.write('.'))
                .pipe(gulp.dest(`./static/module/${module}/css`));
    } else if (et === env.pro) {
        return gulp.src(`static/module/${module}/scss/index.css`)
                .pipe(postcss(postcssPlugin(et, module)))
                .pipe(cssnano())
                .pipe(gulp.dest(`./dist/${config.name}/${config.version}/${module}/`));
    }
};

/**
 * postcss编译
 * @param fp String/Undefined 静态资源模块名
 * @param et Symbol 必填 环境
 */
const postcssCompile = (fp, et) => {
    if (typeof fp === 'symbol') {

        //只传一个参数时为环境参数
        fs.readdir('static/module', (err, data) => {
            if (err) {
                console.log(err);
                return;
            }

            for (let f of data) {
                compileForModule(f, fp);
            }
        });
    } else {
        return compileForModule(fp, et);
    }
};

//css watch
gulp.task('postcss-watch', () => {
    gulp.watch(['static/common/**/*.css', 'static/module/*/scss/**/*.css'], (e) => {
        var epath = e.path;

        //模块中文件更改,只重新编译当前模块的css;否则,重新编译所有模块的css
        if (/module/.test(epath)) {
            let module = epath.match(/module[\\|\/](.*)[\\|\/]scss/); //兼容\和/型的路径

            if (module && module[1]) {
                postcssCompile(module[1], env.dev);
            } else {
                return;
            }

        } else {
            postcssCompile(env.dev);
        }
    });
});

// assets dest
gulp.task('assets', function() {
    return gulp.src('static/assets/**')
        .pipe(gulp.dest(`${rootdir}/assets`));
});

gulp.task('ge', ['assets'], () => {

    //compile postcss
    postcssCompile(env.pro);
});