gulpfile.js 5.15 KB
/**
 * gulp
 * author: xuqi(qi.xu@yoho.cn)
 * date: 2015/9/30
 */

var gulp = require('gulp');
var path = require('path');
var webpack = require('webpack');
var gutil = require('gulp-util');
var WebpackDevServer = require('webpack-dev-server');

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

var named = require('vinyl-named');

var cp = require('child_process');
var fs = require('fs');
var config = require('./package');
var root = `dist/${config.name}/`;

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

//webpack config
var webpackConfig = require('./webpack.config.js');

gulp.task('default', ['postcss-dev', 'postcss-watch', 'webpack-server']);


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

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

            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,
    plugins;

    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
        };

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

    plugins = [
        require('autoprefixer')({
            browsers: ['not ie < 8']
        }),
        require('precss'),
        require('postcss-assets')(assets),
        require('postcss-sprites').default(sprites),
        require('postcss-calc'),
        require('postcss-opacity'),
        require('stylelint')(),
        require('postcss-reporter')({ clearMessages: true }),

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

    //正式环境为assets和img加no-cache
    if (env === 'PRO') {
        plugins.push(require('postcss-cachebuster')({
            imagesPath: '/' + distDir.img,
            cssPath: '/' + distDir.css
        }))
    }

    return plugins;
}

//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))
});

gulp.task('js', function() {
    var proConfig = Object.assign({}, webpackConfig);

    proConfig.plugins.concat(
        new webpack.DefinePlugin({
            "process.env": {
                "NODE_ENV": JSON.stringify("production")
            }
        }),
        new webpack.optimize.DedupePlugin(),
        new webpack.optimize.UglifyJsPlugin()
    );

    return gulp.src('./index.js')
        .pipe(named())
        .pipe(webpack(proConfig))
        .pipe(gulp.dest(distDir.js))
});

//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))
});

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

//server
gulp.task('server', () => {
    cp.exec('npm run start', (err, stdout, stderr) => {
        if (err) {
            console.log(`exec error: ${err}`);
        }
    });
});

//webpack server
gulp.task('webpack-server', (cb) => {
    var devConfig = Object.assign({}, webpackConfig, {
        entry: './index.js',
        output: {
            path: path.resolve(__dirname, '/build'),
            filename: 'bundle.js'
        },
        plugins: []//TODO: 没理清commonChunkPlugin加载后文件访问问题??
    });

    new WebpackDevServer(webpack(devConfig), {
        inline: true,
        stats: {
            clors: true
        }
    }).listen(8002, 'localhost', (err) => {
        if (err) {
            throw new gutil.PluginError('webpack-server-server', err);
        }
        gutil.log('[webpack-server]', 'http://localhost:8002/');
    });
});