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中实现函数数组的方法
Dec 25 Javascript
js与jquery回车提交的方法
Feb 03 Javascript
Javascript实现单例模式
Jan 24 Javascript
AngularJS基础 ng-keyup 指令简单示例
Aug 02 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
Sep 14 Javascript
简单实现JS倒计时效果
Dec 23 Javascript
zTree树形插件异步加载方法详解
Jun 14 Javascript
angularjs通过过滤器返回超链接的方法
Oct 26 Javascript
Vue 使用计时器实现跑马灯效果的实例代码
Jul 11 Javascript
vue项目在webpack2实现移动端字体自适配功能
Jun 02 Javascript
JavaScript实现世界各地时间显示
Sep 07 Javascript
浅析VUE防抖与节流
Nov 24 Vue.js
基于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
整理的一些实用WordPress后台MySQL操作命令
2013/01/07 PHP
PHP中的类型约束介绍
2015/05/11 PHP
php获取ajax的headers方法与内容实例
2017/12/27 PHP
PHP实现普通hash分布式算法简单示例
2018/08/06 PHP
Yii2结合Workerman的websocket示例详解
2018/09/10 PHP
使用Math.floor与Math.random取随机整数的方法详解
2013/05/07 Javascript
js去空格技巧分别去字符串前后、左右空格
2013/10/21 Javascript
AngularJS 实现按需异步加载实例代码
2015/10/18 Javascript
JavaScript如何实现组合列表框中元素移动效果
2016/03/01 Javascript
谈一谈bootstrap响应式布局
2016/05/23 Javascript
总结AngularJS开发者最常犯的十个错误
2016/08/31 Javascript
JS动态给对象添加属性和值的实现方法
2016/10/21 Javascript
Angular开发者指南之入门介绍
2017/03/05 Javascript
nodejs+websocket实时聊天系统改进版
2017/05/18 NodeJs
React中使用collections时key的重要性详解
2017/08/07 Javascript
微信小程序商品详情页的底部弹出框效果
2020/11/16 Javascript
详解小程序输入框闪烁及重影BUG解决方案
2018/08/31 Javascript
[38:40]2018DOTA2亚洲邀请赛 4.6淘汰赛 mineski vs LGD 第一场
2018/04/10 DOTA
在python的WEB框架Flask中使用多个配置文件的解决方法
2014/04/18 Python
python函数中return后的语句一定不会执行吗?
2017/07/06 Python
python处理Excel xlrd的简单使用
2017/09/12 Python
Python+tkinter模拟“记住我”自动登录实例代码
2018/01/16 Python
pycharm通过ssh连接远程服务器教程
2020/02/12 Python
Python中的sys.stdout.write实现打印刷新功能
2020/02/21 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
X/HTML5 和 XHTML2
2008/10/17 HTML / CSS
瑞典耳机品牌:URBANISTA
2019/12/03 全球购物
采购经理岗位职责
2014/02/16 职场文书
眼镜促销方案
2014/03/15 职场文书
报考公务员诚信承诺书
2014/08/29 职场文书
一年级班主任工作总结2014
2014/11/08 职场文书
国庆节主题班会
2015/08/15 职场文书
初二英语教学反思
2016/02/15 职场文书
windows下快速安装nginx并配置开机自启动的方法
2021/05/11 Servers
一篇文章了解正则表达式的替换技巧
2022/02/24 Javascript
Python开发简易五子棋小游戏
2022/05/02 Python