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 相关文章推荐
10款新鲜出炉的 jQuery 插件(Ajax 插件,有幻灯片、图片画廊、菜单等)
Jun 08 Javascript
jQuery插件原来如此简单 jQuery插件的机制及实战
Feb 07 Javascript
一个JQuery操作Table的代码分享
Mar 30 Javascript
将Datatable转化成json发送前台实现思路
Sep 06 Javascript
js判读浏览器是否支持html5的canvas的代码
Nov 18 Javascript
javascript利用apply和arguments复用方法
Nov 25 Javascript
jquery实现可自动收缩的TAB网页选项卡代码
Sep 06 Javascript
JavaScript的函数式编程基础指南
Mar 19 Javascript
小程序实现授权登陆的解决方案
Dec 02 Javascript
JS计算两个数组的交集、差集、并集、补集(多种实现方式)
May 21 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
Aug 17 Javascript
对layui初始化列表的CheckBox属性详解
Sep 13 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&&mysql)五
2006/10/09 PHP
PHP 开发工具
2006/12/06 PHP
php cookie的操作实现代码(登录)
2010/12/29 PHP
PHP Session_Regenerate_ID函数双释放内存破坏漏洞
2011/01/27 PHP
ECshop 迁移到 PHP7版本时遇到的兼容性问题
2016/02/15 PHP
搜索附近的人PHP实现代码
2018/02/11 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
PHP7.3.10编译安装教程
2019/10/08 PHP
比较简单的一个符合web标准的JS调用flash方法
2007/11/29 Javascript
有关于eclipse配置spket需要注意的一些地方
2013/04/07 Javascript
基于NodeJS的前后端分离的思考与实践(一)全栈式开发
2014/09/26 NodeJs
浅谈Javascript中匀速运动的停止条件
2014/12/19 Javascript
jQuery中事件与动画的总结分享
2016/05/24 Javascript
jQuery Easyui学习教程之实现datagrid在没有数据时显示相关提示内容
2016/07/09 Javascript
动态加载css方法实现和深入解析
2017/01/18 Javascript
js 性能优化之算法和流程控制
2017/02/15 Javascript
jQuery中过滤器的基本用法示例
2017/10/11 jQuery
在 Angular中 使用 Lodash 的方法
2018/02/11 Javascript
vue项目中,main.js,App.vue,index.html的调用方法
2018/09/20 Javascript
js实现GIF动图分解成多帧图片上传
2019/10/24 Javascript
[04:03]2014DOTA2西雅图国际邀请赛 LGD战队巡礼
2014/07/07 DOTA
详解Python3操作Mongodb简明易懂教程
2017/05/25 Python
Windows系统下多版本pip的共存问题详解
2017/10/10 Python
Python3中条件控制、循环与函数的简易教程
2017/11/21 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
2018/06/09 Python
python的常见矩阵运算(小结)
2019/08/07 Python
flask 实现token机制的示例代码
2019/11/07 Python
python sorted函数原理解析及练习
2020/02/10 Python
PyQt5 控件字体样式等设置的实现
2020/05/13 Python
Python分析最近大火的网剧《隐秘的角落》
2020/07/02 Python
用HTML5 Canvas API中的clearRect()方法实现橡皮擦功能
2016/03/15 HTML / CSS
生产现场工艺工程师岗位职责
2013/11/28 职场文书
满月酒主持词
2014/03/27 职场文书
小学班主任事迹材料
2014/12/17 职场文书
2015年小学生国庆节演讲稿
2015/07/30 职场文书
祝福语集锦:给妹妹结婚的祝福语
2019/12/18 职场文书