webpack+gulp 构建react项目

@拭目以待:首发于webpack+gulp 构建react项目

背景

GirdManager首页,使用 React 实现。

需要实现功能
  1. jsx 转换为 js
  2. es6 转换为 es5
  3. 对文件进行合并、压缩
  4. 生成可供发布的zip包
  5. 单个页面只引入当前使用到的资源文件
为什么要将 webpack gulp 配合使用

webpack 在使用过程中, 并不能很好的解决文件相关的操作。所以采用 gulp 进行配合。

webpack 与 gulp 各自实现的功能如下:

webpack

  1. jsx transform js
  2. es6 transform es5

gulp

  1. 文件操作
  2. 压缩html css js
  3. 生成发布所需zip包
实现源码

gulpfile.js

/*
* 文件操作
* 压缩html css
* 对js相关的操作使用webpack
* */
const gulp = require('gulp');
const htmlmin = require('gulp-htmlmin');
const minifyCss = require('gulp-minify-css');
const uglify = require('gulp-uglify');
const gulpIf = require('gulp-if');
const gulpUtil = require('gulp-util');
const zip = require('gulp-zip');
const del = require('del');
var miniHtmlOptions = {
    removeComments: true,  //清除HTML注释
    collapseWhitespace: true,  //压缩HTML
    collapseBooleanAttributes: false,  //省略布尔属性的值 <input checked="true"/> ==> <input checked />
    removeEmptyAttributes: true,  //删除所有空格作属性值 <input id="" /> ==> <input />
    removeScriptTypeAttributes: true,  //删除<script>的type="text/javascript"
    removeStyleLinkTypeAttributes: true,  //删除<style>和<link>的type="text/css"
    minifyJS: true,  //压缩页面JS
    minifyCSS: true  //压缩页面CSS
};
// 构建项目目录
var buildPath = 'GridManager';
// 打包后的名称
var zipName = 'GridManagerSite.zip';
var webpack = require('webpack');
var webpackConfig = require('./webpack.config.js');
// 默认执行
gulp.task('default', ['develop']);
// 构建开发包
gulp.task('develop', ['webpack:build']);
// 构建上线包
gulp.task('production', ['uglify'], function(){
    // gulp.start('uglify');
});
// 构造前: 删除原有构建包
gulp.task('clean', function() {
    del.sync([buildPath + '/*']);
});
// 构造前: 先删除之前的.zip
gulp.task('cleanzip', function(){
    del.sync(zipName);
});
// 移动文件,除jsx以外
gulp.task('movefile', ['clean', 'cleanzip'], function () {
    return gulp.src(['src/*app*/*/*', 'src/*assets*/*/*', 'src/index.html', '!src/**/*.js*'])
        .pipe(gulp.dest(buildPath));
});
// 压缩
gulp.task('uglify', ['webpack:build'], function(){
    return gulp.src([buildPath + '/**/*'])
        .pipe(gulpIf('*.html', htmlmin(miniHtmlOptions).on('error', gulpUtil.log)))
        .pipe(gulpIf('*.js', uglify().on('error', gulpUtil.log)))
        .pipe(gulpIf('*.css', minifyCss()))
        .pipe(gulp.dest(buildPath));
});
// 使用webpack 对jsx进行处理
gulp.task('webpack:build', ['movefile'], function(callback) {
    // modify some webpack config options
    var myConfig = Object.create(webpackConfig);
    // run webpack
    webpack(myConfig, function(err, stats) {
        if(err) throw new gutil.PluginError('webpack:build', err);
        gulpUtil.log('[webpack:build]', stats.toString({
            colors: true
        }));
        callback();
    });
});
//打包为GridManagerSite.zip
gulp.task('GridManagerSite', function() {
    console.log('GridManagerSite');
    return gulp.src([buildPath + '/**/*.*'])
        .pipe(zip(zipName))
        .pipe(gulp.dest(''));
});
/**
 * 命令所对应功能:
 * gulp: 构建未压缩的项目
 * gulp develop: 构建未压缩的项目
 * gulp production: 构建压缩的项目, 并生成zip包
 * */

webpack.config.js

/*
* webpack只对js进行控制
* jsx transform js
* es6 transform es5
* 注意:
* html,css 及打包压缩等使用gulp实现
* */
var webpack = require('webpack');
var path = require('path');
var buildPath = 'GridManager';
module.exports = {
    entry: {
        'index': ['./src/app/model.js', './src/app/index.jsx'],
        'about': './src/app/about/index.jsx',
        'api': './src/app/api/index.jsx',
        'demo': ['./src/app/demo/model.js', './src/app/demo/index.jsx'],
        'faq': './src/app/faq/index.jsx',
        'version': './src/app/version/index.jsx',
        'common': ['./src/common/header.jsx', './src/common/footer.jsx', './src/common/tool.js']
    },
    output: {
        path: path.join(__dirname, buildPath),
        filename: '[name].build.js',
        publicPath: '/' + buildPath + ''
    },
    module: {
        loaders: [
            {
                test: /.js?$/,
                loaders: ['babel?{"presets":["es2015"]}'],
                exclude: /(node_modules|bower_components)/,
                include: [path.join(__dirname, 'src')]
            },
            {
                test: /.jsx$/,
                loader: 'babel-loader!jsx-loader?harmony'
            },
            {
                test: /.html$/,
                loader: 'file?name=[path][name]-[hash:20].[ext]',
                exclude: [/(node_modules|bower_components)/],
                include: [path.join(__dirname, 'src/app')]
            }
        ]
    }
};
注意事项

1.在 gulpfile.js 中调用 webpack

gulp.task('webpack:build', function(callback) {
    // webpackConfig 为 webpack.config.js 中的内容
    var myConfig = Object.create(webpackConfig);
    // run webpack
    webpack(myConfig, function(err, stats) {
        if(err) throw new gutil.PluginError('webpack:build', err);
        gulpUtil.log('[webpack:build]', stats.toString({
            colors: true
        }));
        callback();
    });
});

2.存在js的压缩时, 必须在压缩前先执行 webpack 。以保证在执行压缩时, 已经将全部的 jsx 转换为 js

gulp.task('uglify', ['webpack:build'], function(){
    return gulp.src([buildPath + '/**/*'])
        .pipe(gulpIf('*.html', htmlmin(miniHtmlOptions).on('error', gulpUtil.log)))
        .pipe(gulpIf('*.js', uglify().on('error', gulpUtil.log)))
        .pipe(gulpIf('*.css', minifyCss()))
        .pipe(gulp.dest(buildPath));
});

@拭目以待

个人站点:www.lovejavascript.com
表格管理插件:gridmanager.lovejavascript.com && github地址
QQ交流群 (452781895):How To Make Love
微信公众账号:loveJavascript

《野生前端工程师》专辑中所有文章均为@拭目以待 原创,转载请注明出处。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在现在的前端开发中,前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等等一些原本后端的思想开始...
    Charlot阅读 10,842评论 1 32
  • 在现在的前端开发中,前后端分离、模块化开发、版本控制、文件合并与压缩、mock数据等等一些原本后端的思想开始逐渐渗...
    彬_仔阅读 25,704评论 21 139
  • 最近在学习 Webpack,网上大多数入门教程都是基于 Webpack 1.x 版本的,我学习 Webpack 的...
    My_Oh_My阅读 12,520评论 40 247
  • -- 1. Gulp VS webpack 比较 Gulp 是一个任务管理工具,让简单的任务更清晰,让复杂的任务易...
    慢清尘阅读 8,889评论 7 16
  • 同属江南 跟水乡一样有诗意 徽州又有着自己的味道。 慢节奏 是这个时代难能可贵的秉性 顺势就在快中解放出来 小巷深...
    补拙莫如勤LV阅读 1,839评论 0 2