webpack 2的react开发配置实例代码


Posted in Javascript onJuly 28, 2017

基于webpack 2.3的标准语法,包含了less变量替换、React组件热加载、第三库单独输出、区分生产与开发环境等常用配置。

'use strict'

module.exports = function( env ) {
  // 生成环境下webpack使用-p参数开启代码压缩
  // webpack[-dev-server]使用--env dev参数指定编译环境
  var isDev = env == 'dev';

  var path = require( 'path' );
  var webpack = require( 'webpack' );
  var CleanWebpackPlugin = require( 'clean-webpack-plugin' );
  var CopyWebpackPlugin = require( 'copy-webpack-plugin' );
  var HtmlWebpackPlugin = require( 'html-webpack-plugin' );
  var WebkitPrefixer = require( 'autoprefixer' );
  var WebpackMd5Hash = require( 'webpack-md5-hash' );
  var BundleAnalyzerPlugin = require( 'webpack-bundle-analyzer' ).BundleAnalyzerPlugin;

  var sourcedir = path.resolve( __dirname, 'src' );// 源码和资源文件的放置位置
  var outputdir = path.resolve( __dirname, 'build' );// 编译结果的放置位置
  var webContextRoot = '/myreact/';// 应用的实际访问路径,默认是'/'
  // antd的图标字体文件的实际访问路径,利用less-load的变量替换功能
  var antd_fonticon = webContextRoot + 'assets/antd_fonticon/iconfont';

  var hasValue = function( item ) { return item != null; };
  return {
    //context: path.resolve( __dirname ),
    devtool: 'source-map',
    devServer: {
      host: '0.0.0.0',
      port: 8082,
      historyApiFallback: true
    },
    resolve: {
      // 让less-loader等插件能找到以~相对定位的资源
      modules: [sourcedir, 'node_modules']
    },
    entry: {
      main: [
        // 编译新版本js的新api(如Promise),主要是让IE11能够执行编译后的代码
        'babel-polyfill',
        //使用react-hot-loader@3.0.0-beta.6,
        // 搭配webpack-dev-server --hot命令实现react组件的hot reload
        isDev ? 'react-hot-loader/patch' : null,
        path.resolve( sourcedir, 'main.jsx' )].filter( hasValue ),
      // 第三方库汇总输出
      vendor: ['bootstrap/dist/css/bootstrap.min.css', 'react',
        'react-dom', 'react-router', 'redux', 'react-redux',
        'react-router-redux', 'moment', 'lodash', 'immutable', 'whatwg-fetch',
        // 只含antd的js部分
        'antd',
        // 各控件还需引入各自的样式文件
        'antd/lib/style/index.less']
    },
    output: {
      path: outputdir,
      filename: isDev ? 'js/[name].js' : 'js/[name]_[chunkhash:8].js',
      // 使用require.ensure造成的延迟加载的代码文件
      chunkFilename: isDev ? 'js/chunk_[id]_[name].js'
        : 'js/chunk_[name]_[chunkhash:8].js',
      publicPath: webContextRoot
    },
    module: {
      rules: [{
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        use: [{
          // 编译新版本js语法为低版本js语法
          loader: 'babel-loader',
          options: {
            presets: [
              // 编译es2015版本的js
              ['babel-preset-es2015', {
                modules: false
              }], 'babel-preset-stage-2',
              // 编译jsx
              'babel-preset-react'],

            plugins: [// 支持热加载react组件
              isDev ? 'react-hot-loader/babel' : null,
              // 减少重复的编译后的辅助方法
              'babel-plugin-transform-runtime',
              // 按需加载组件的代码和样式
              ['babel-plugin-import', {
                libraryName: 'antd',
                style: true
              }]].filter( hasValue )
          }
        }]
      }, {
        test: /\.css$/,
        use: ['style-loader',
          {
            loader: 'css-loader',
            options: {
              // 第三方组件未以module方式引入css,所以不能在全局开启css module
              modules: false
            }
          },
          { loader: 'postcss-loader', options: { plugins: [WebkitPrefixer] } }]
      }, {
        test: /\.less$/,
        use: ['style-loader',
          {
            loader: 'css-loader',
            options: {
              modules: false
            }
          },
          { loader: 'postcss-loader', options: { plugins: [WebkitPrefixer] } },
          {
            loader: 'less-loader',
            options: {
              modules: false,
              modifyVars: {
                // 替换antd用到的字体文件路径
                "icon-url": JSON.stringify( antd_fonticon )
              }
            }
          }]
      }, {
        test: /\.(jpg|png|gif)$/,
        use: {
          loader: 'url-loader',
          options: {
            // 编码为dataUrl的最大尺寸
            limit: 10000,
            // 输出路径,相对于publicPath
            outputPath: 'assets/',
            name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
          }
        }

      }, {
        test: /\.(woff|woff2)(\?v=\d+\.\d+\.\d+)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
            mimetype: 'application/font-woff',
            outputPath: 'assets/',
            name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
          }
        }
      }, {
        test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
            mimetype: 'application/octet-stream',
            outputPath: 'assets/',
            name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
          }
        }
      }, {
        test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
            mimetype: 'application/vnd.ms-fontobject',
            outputPath: 'assets/',
            name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
          }
        }
      }, {
        test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 10000,
            mimetype: 'application/svg+xml',
            outputPath: 'assets/',
            name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
          }
        }
      }]
    },
    plugins: [
      // momentjs包含大量本地化代码,需筛选
      new webpack.ContextReplacementPlugin( /moment[\/\\]locale$/, /en-ca|zh-cn/ ),
      new webpack.optimize.OccurrenceOrderPlugin( true ),
      // 复制无需编译的文件至输出目录
      new CopyWebpackPlugin( [{
        from: path.resolve( sourcedir, 'assets' ),
        to: 'assets'
      }] ),
      // 修复webpack的chunkhash不以chunk文件实际内容为准的问题
      new WebpackMd5Hash(),
      // 单独打包输出第三方组件,和webpack生成的运行时代码
      new webpack.optimize.CommonsChunkPlugin( {
        name: ['vendor', 'manifest']
      }),
      // 自动填充js、css引用进首页
      new HtmlWebpackPlugin( {
        title: 'wzp react',
        template: path.resolve( sourcedir, 'index.html' ),
        inject: 'body' // Inject all scripts into the body
      }),
      // 设置环境变量
      new webpack.DefinePlugin( {
        process: {
          env: {
            // process.env.NODE_ENV==="production"
            // 应用代码里,可凭此判断是否运行在生产环境
            NODE_ENV: isDev ? JSON.stringify( 'development' )
              : JSON.stringify( 'production' )
          }
        }
      }),
      // print more readable module names on HMR updates
      isDev ? new webpack.NamedModulesPlugin() : null,
      // 先清理输出目录
      isDev ? null : new CleanWebpackPlugin( [outputdir] ),
      // 排除特定库
      isDev ? null : new webpack.IgnorePlugin( /.*/, /react-hot-loader$/ ),
      // 输出报告,查看第三方库的大小
      isDev ? null : new BundleAnalyzerPlugin(
        {
          analyzerMode: 'static',
          reportFilename: 'report.html',
          openAnalyzer: true,
          generateStatsFile: false
        })
    ].filter( hasValue )
  }
};

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JAVASCRIPT  THIS详解 面向对象
Mar 25 Javascript
prototype与jquery下Ajax实现的差别
Sep 13 Javascript
多种方法判断Javascript对象是否存在
Sep 22 Javascript
js实现缓冲运动效果的方法
Apr 10 Javascript
javascript HTML5 canvas实现打砖块游戏
Jun 18 Javascript
js只执行1次的函数示例
Jul 20 Javascript
浅谈js常用内置方法和对象
Sep 24 Javascript
ES6深入理解之“let”能替代”var“吗?
Jun 28 Javascript
vue axios 在页面切换时中断请求方法 ajax
Mar 05 Javascript
基于jquery实现左右上下移动效果
May 02 jQuery
基于Vue+element-ui 的Table二次封装的实现
Jul 20 Javascript
vue router 配置路由的方法
Jul 26 Javascript
基于AngularJS实现表单验证功能
Jul 28 #Javascript
AngularJS service之select下拉菜单效果
Jul 28 #Javascript
解决Vue2.0自带浏览器里无法打开的原因(兼容处理)
Jul 28 #Javascript
bootstrap datepicker插件默认英文修改为中文
Jul 28 #Javascript
基于BootStrap multiselect.js实现的下拉框联动效果
Jul 28 #Javascript
基于JS实现移动端左滑删除功能
Jul 28 #Javascript
Vue2.0 多 Tab切换组件的封装实例
Jul 28 #Javascript
You might like
PHP新手上路(七)
2006/10/09 PHP
php实现的遍历文件夹下所有文件,编辑删除
2010/01/05 PHP
PHP连接SQLServer2005的实现方法(附ntwdblib.dll下载)
2012/07/02 PHP
使用图灵api创建微信聊天机器人
2015/07/23 PHP
jQuery在html有效在jsp无效的原因及解决方法
2013/08/02 Javascript
JS 实现导航栏悬停效果(续2)
2013/09/24 Javascript
利用函数的惰性载入提高javascript代码执行效率
2014/05/05 Javascript
jQuery提交多个表单的小技巧
2014/07/27 Javascript
JavaScript onkeydown事件入门实例(键盘某个按键被按下)
2014/10/17 Javascript
js鼠标滑过图片震动特效的方法
2015/02/17 Javascript
js实现模拟银行卡账号输入显示效果
2015/11/18 Javascript
JavaScript ES6中CLASS的使用详解
2016/11/22 Javascript
详解微信小程序 页面跳转 传递参数
2016/12/08 Javascript
webpack入门+react环境配置
2017/02/08 Javascript
discuz表情的JS提取方法分析
2017/03/22 Javascript
浅谈微信页面入口文件被缓存解决方案
2018/09/29 Javascript
浅谈React Native 传参的几种方式(小结)
2019/05/21 Javascript
Vue.js中的组件系统
2019/05/30 Javascript
VueCli4项目配置反向代理proxy的方法步骤
2020/05/17 Javascript
vue-cli3中配置alias和打包加hash值操作
2020/09/04 Javascript
全面解析Vue中的$nextTick
2020/12/24 Vue.js
python中将一个全部为int的list 转化为str的list方法
2018/04/09 Python
详解python中的装饰器
2018/07/10 Python
python读取excel指定列数据并写入到新的excel方法
2018/07/10 Python
Python编程中flask的简介与简单使用
2018/12/28 Python
python实现翻转棋游戏(othello)
2019/07/29 Python
零基础小白多久能学会python
2020/06/22 Python
Python OpenCV去除字母后面的杂线操作
2020/07/05 Python
HTML5 虚拟键盘出现挡住输入框的解决办法
2017/02/14 HTML / CSS
微软中国官方商城:Microsoft Store中国
2018/10/12 全球购物
KELLER SPORTS荷兰:在线订购最好的运动产品
2020/10/13 全球购物
2019年Java面试必问之经典试题
2012/09/12 面试题
写自荐信要注意什么
2013/12/26 职场文书
大二学期个人自我评价
2014/01/13 职场文书
2015年妇幼保健工作总结
2015/05/19 职场文书
入党积极分子考察意见
2015/06/02 职场文书