/** * Yohobuy 构建脚本 * @author: xuqi<qi.xu@yoho.cn> * @date: 2016/4/25 */ 'use strict'; const path = require('path'); const gulp = require('gulp'); const _ = require('lodash'); const gutil = require('gulp-util'); const ftp = require('gulp-ftp'); const postcss = require('gulp-postcss'); const sourcemaps = require('gulp-sourcemaps'); const cssnano = require('gulp-cssnano'); const rename = require('gulp-rename'); const webpack = require('webpack'); const WebpackDevServer = require('webpack-dev-server'); const webpackConfig = require('./webpack.config.js'); const env = { dev: Symbol('development'), pro: Symbol('production') }; const config = require('../package.json'); const ftpConfig = { host: '218.94.75.58', user: 'php', pass: 'yoho9646' }; const distRoot = `dist/${config.name}`; const dist = { js: `${distRoot}/${config.version}`, css: `${distRoot}/${config.version}`, assets: `${distRoot}/assets`, img: `${distRoot}/${config.version}/img`, font: `${distRoot}/${config.version}/font` }; /** * postcss plugins for both dev and pro * @parem et Symbol */ const postcssPlugin = (et) => { var sprites = { spritesmith: { padding: 2 }, groupBy(file) { var dir = _.last(path.parse(file.styleFilePath).dir.split(path.sep)); var group = dir === 'scss' ? path.basename(file.styleFilePath, '.css') : dir; 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 }; Object.assign(sprites, { basePath: dist.img, stylesheetPath: dist.css, spritePath: dist.img }); } else if (et === env.dev) { assets = { loadPaths: ['img/', 'font/'], relativeTo: 'css/' }; Object.assign(sprites, { basePath: 'img/', stylesheetPath: 'css/', spritePath: '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}` })); } return plugins; }; // default gulp.task('default', ['postcss-dev', 'postcss-watch', 'webpack-dev-server']); // ge gulp.task('ge', ['postcss', 'webpack']); // dist gulp.task('dist', ['ge'], () => { var ftpstream = ftp(ftpConfig); return gulp.src('dist/**/') .pipe(ftpstream) .pipe(gutil.noop()); }); // postcss compile in dev gulp.task('postcss-dev', () => { return gulp.src(['scss/base.css', 'scss/*/_index.css', '!scss/plugin/*', '!scss/common/*']) .pipe(sourcemaps.init()) .pipe(postcss(postcssPlugin(env.dev))) .on('error', function(err) { gutil.log(err); this.emit('end'); }) .pipe(rename((cssPath) => { if (cssPath.dirname === '.') { return; } cssPath.basename = `${cssPath.dirname}`; cssPath.dirname = './'; })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('css/')); }); // postcss file watch gulp.task('postcss-watch', () => { gulp.watch('scss/**/*.css', ['postcss-dev']); }); // copy assets gulp.task('assets', ['img', 'font']); // copy img gulp.task('img', () => { return gulp.src('img/**/*') .pipe(gulp.dest(dist.img)); }); // copy font gulp.task('font', () => { return gulp.src('font/*') .pipe(gulp.dest(dist.font)); }); // postcss compile in pro gulp.task('postcss', ['assets'], () => { return gulp.src(['scss/base.css', 'scss/*/_index.css', '!scss/plugin/*', '!scss/common/*']) .pipe(postcss(postcssPlugin(env.pro))) .pipe(cssnano({zindex: false })) .pipe(rename((cssPath) => { if (cssPath.dirname === '.') { return; } cssPath.basename = `${cssPath.dirname}`; cssPath.dirname = './'; })) .pipe(gulp.dest(dist.css)); }); // webpack dev server gulp.task('webpack-dev-server', () => { var devConfig = Object.assign({}, webpackConfig, { debug: true }); new WebpackDevServer(webpack(devConfig), { contentBase: '.', publicPath: '//localhost:5002/', hot: true, stats: { colors: true }, headers: { 'Access-Control-Allow-Origin': '*' } }).listen(5002, '0.0.0.0', (err) => { if (err) { throw new gutil.PluginError('webpack-dev-server', err); } gutil.log('[webpack-serve]', 'http://localhost:5002/'); }); }); // webpack compile in pro gulp.task('webpack', (done) => { var proConfig = Object.assign({}, webpackConfig); proConfig.output.path = dist.js; proConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, properties: false }, output: { keep_quoted_props: true } })); webpack(proConfig, (err, stats) => { if (err) { throw new gutil.PluginError('webpack', err); } gutil.log('[webpack compile]:', stats.endTime - stats.startTime, 'ms'); done(); }); });