webpack 2的react开发配置实例

基于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$/,options: {
                            modules: false
                        }
                    },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+)?$/,options: {
                        limit: 10000,mimetype: 'application/font-woff',outputPath: 'assets/',name: isDev ? '[name].[ext]' : '[name]_[hash:8].[ext]'
                    }
                }
            },{
                test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,mimetype: 'application/octet-stream',{
                test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,mimetype: 'application/vnd.ms-fontobject',{
                test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,mimetype: 'application/svg+xml',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 )
    }
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


react 中的高阶组件主要是对于 hooks 之前的类组件来说的,如果组件之中有复用的代码,需要重新创建一个父类,父类中存储公共代码,返回子类,同时把公用属性...
我们上一节了解了组件的更新机制,但是只是停留在表层上,例如我们的 setState 函数式同步执行的,我们的事件处理直接绑定在了 dom 元素上,这些都跟 re...
我们上一节了解了 react 的虚拟 dom 的格式,如何把虚拟 dom 转为真实 dom 进行挂载。其实函数是组件和类组件也是在这个基础上包裹了一层,一个是调...
react 本身提供了克隆组件的方法,但是平时开发中可能很少使用,可能是不了解。我公司的项目就没有使用,但是在很多三方库中都有使用。本小节我们来学习下如果使用该...
mobx 是一个简单可扩展的状态管理库,中文官网链接。小编在接触 react 就一直使用 mobx 库,上手简单不复杂。
我们在平常的开发中不可避免的会有很多列表渲染逻辑,在 pc 端可以使用分页进行渲染数限制,在移动端可以使用下拉加载更多。但是对于大量的列表渲染,特别像有实时数据...
本小节开始前,我们先答复下一个同学的问题。上一小节发布后,有小伙伴后台来信问到:‘小编你只讲了类组件中怎么使用 ref,那在函数式组件中怎么使用呢?’。确实我们...
上一小节我们了解了固定高度的滚动列表实现,因为是固定高度所以容器总高度和每个元素的 size、offset 很容易得到,这种场景也适合我们常见的大部分场景,例如...
上一小节我们处理了 setState 的批量更新机制,但是我们有两个遗漏点,一个是源码中的 setState 可以传入函数,同时 setState 可以传入第二...
我们知道 react 进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解...
在平时工作中的某些场景下,你可能想在整个组件树中传递数据,但却不想手动地通过 props 属性在每一层传递属性,contextAPI 应用而生。
楼主最近入职新单位了,恰好新单位使用的技术栈是 react,因为之前一直进行的是 vue2/vue3 和小程序开发,对于这些技术栈实现机制也有一些了解,最少面试...
我们上一节了了解了函数式组件和类组件的处理方式,本质就是处理基于 babel 处理后的 type 类型,最后还是要处理虚拟 dom。本小节我们学习下组件的更新机...
前面几节我们学习了解了 react 的渲染机制和生命周期,本节我们正式进入基本面试必考的核心地带 -- diff 算法,了解如何优化和复用 dom 操作的,还有...
我们在之前已经学习过 react 生命周期,但是在 16 版本中 will 类的生命周期进行了废除,虽然依然可以用,但是需要加上 UNSAFE 开头,表示是不安...
上一小节我们学习了 react 中类组件的优化方式,对于 hooks 为主流的函数式编程,react 也提供了优化方式 memo 方法,本小节我们来了解下它的用...
开源不易,感谢你的支持,❤ star me if you like concent ^_^
hel-micro,模块联邦sdk化,免构建、热更新、工具链无关的微模块方案 ,欢迎关注与了解
本文主题围绕concent的setup和react的五把钩子来展开,既然提到了setup就离不开composition api这个关键词,准确的说setup是由...
ReactsetState的执行是异步还是同步官方文档是这么说的setState()doesnotalwaysimmediatelyupdatethecomponent.Itmaybatchordefertheupdateuntillater.Thismakesreadingthis.staterightaftercallingsetState()apotentialpitfall.Instead,usecom