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 相关文章推荐
33个优秀的 jQuery 图片展示插件分享
Mar 14 Javascript
sencha touch 模仿tabpanel导航栏TabBar的实例代码
Oct 24 Javascript
Javascript基础教程之函数对象和属性
Jan 18 Javascript
jQuery中trigger()与bind()用法分析
Dec 18 Javascript
使用DeviceOne实现微信小程序功能
Dec 29 Javascript
a标签置灰不可点击的实现方法
Feb 06 Javascript
bootstrap table 多选框分页保留示例代码
Mar 08 Javascript
JavaScript基础之静态方法和实例方法分析
Dec 26 Javascript
vue实现动态显示与隐藏底部导航的方法分析
Feb 11 Javascript
jQuery Ajax async=>false异步改为同步时,解决导致浏览器假死的问题
Jul 22 jQuery
微信提示 在浏览器打开 效果实现过程解析
Sep 10 Javascript
js 执行上下文和作用域的相关总结
Feb 08 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桌面中心(四) 数据显示
2007/03/11 PHP
php一个解析字符串排列数组的方法
2015/05/12 PHP
以实例全面讲解PHP中多进程编程的相关函数的使用
2015/08/18 PHP
PHP上传文件参考配置大文件上传
2015/12/16 PHP
PHP中的session安全吗?
2016/01/22 PHP
THINKPHP3.2使用soap连接webservice的解决方法
2017/12/13 PHP
php多进程并发编程防止出现僵尸进程的方法分析
2020/02/28 PHP
如何让easyui gridview 宽度自适应窗口改变及fitColumns应用
2013/01/25 Javascript
extjs3 combobox取value和text案例详解
2013/02/06 Javascript
jquery 动态创建元素的方式介绍及应用
2013/04/21 Javascript
javascript alert乱码的解决方法
2013/11/05 Javascript
js图片滚动效果时间可随意设定当鼠标移上去时停止
2014/06/26 Javascript
javascript中Date()函数在各浏览器中的显示效果
2015/06/18 Javascript
JS控制静态页面传递参数并获取参数应用
2016/08/10 Javascript
Express之get,pos请求参数的获取
2017/05/02 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
2017/05/22 Javascript
详解VueJS 数据驱动和依赖追踪分析
2017/07/26 Javascript
vue.js $refs和$emit 父子组件交互的方法
2017/12/20 Javascript
详解Vue-Router源码分析路由实现原理
2019/05/15 Javascript
vue在图片上传的时候压缩图片
2020/11/18 Vue.js
vue中activated的用法
2021/01/03 Vue.js
浅谈使用Python变量时要避免的3个错误
2017/10/30 Python
Python栈算法的实现与简单应用示例
2017/11/01 Python
Python实现爬取亚马逊数据并打印出Excel文件操作示例
2019/05/16 Python
keras 自定义loss损失函数,sample在loss上的加权和metric详解
2020/05/23 Python
Keras模型转成tensorflow的.pb操作
2020/07/06 Python
Python+OpenCV检测灯光亮点的实现方法
2020/11/02 Python
医院办公室主任职责
2013/12/29 职场文书
播音主持专业个人自我评价
2014/01/09 职场文书
十八大闭幕感言
2014/01/22 职场文书
创业大赛策划书
2014/03/01 职场文书
2014党员学习兰辉先进事迹思想汇报
2014/09/17 职场文书
大学生十八大感想
2015/08/11 职场文书
Vue CLI中模式与环境变量的深入详解
2021/05/30 Vue.js
golang中字符串MD5生成方式总结
2021/07/04 Golang
Python 全局空间和局部空间
2022/04/06 Python