從零開始React專案架構(四)

ZeroNoob發表於2018-06-13

前言


使用當前的webpack配置能不能打包構建專案呢?當然可以,但這不是我們想要的,所以,讓我們來看一看生產環境需要怎麼配置webpack吧

開發


  1. 生產環境配置
    在根目錄建立webpack.pro.config.js
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
    entry:{
        main:['babel-polyfill','./src/index.js'],        
        vendors: ['react','react-dom','react-router-dom','whatwg-fetch']
    }
    ,
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'bundle.[hash:4].js'
    },
    module:{
        rules:[
            {  
                test: /\.(woff|eot|ttf|svg|png|jpg)$/,  
                use: [  
                    {  
                        loader: 'url-loader',  
                        options: {  
                            limit: '1024' ,
                            name: '[name].[hash:4].[ext]'  
                        }                        
                    },  
                ]  
            },
            {  
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                use: [  
                    {  
                        loader: 'url-loader',  
                        options: {  
                            limit: '1024',
                            name: '[name].[hash:4].[ext]'  
                        }  
                    },  
                ]  
            },
            {
                test: /\.(css|less)$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ["css-loader","less-loader"]
                })
            },
            {
                test:/\.(js|jsx)$/,
                use:"babel-loader",
                exclude:/node_modules/
            }
        ]
    },
    devtool: false,
    plugins:[
        // html 模板外掛
        new HtmlWebpackPlugin({template:'./src/index.html',favicon: './public/favicon.png'}),
        // 啟用作用域提升,讓程式碼檔案更小、執行的更快
        new webpack.optimize.ModuleConcatenationPlugin(),
        // 提取公共程式碼vendors
        new webpack.optimize.CommonsChunkPlugin({
            name:'vendors',
            filename:'[name].[hash:4].js'
        }),
        // 抽離出css
        new ExtractTextPlugin("style.css"),
        // 壓縮js程式碼
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
                drop_console: true,
                pure_funcs: ['console.log']
            }
        }),
        // 定義全域性常量
        new webpack.DefinePlugin({
            "process.env": {
                "NODE_ENV": JSON.stringify("production")
            }
        }),
        // 加署名
        new webpack.BannerPlugin('Copyright by Zero https://github.com/l-Lemon/blog')
    ]
}
複製程式碼

package.json的 script 中加入

"build": "webpack --config webpack.pro.config.js"
複製程式碼

執行 npm run build 根目錄會生成 dist資料夾 和壓縮後的程式碼。

  1. 抽離公共的webpack配置
    我們發現生產環境和開發環境中的webpack配置有很多相同的配置,為了維護性我們最好抽離出來。
    建立webapck.base.js檔案來存我們公共配置
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
// 抽離css
const extractCss = new ExtractTextPlugin("style.css")
// html 模版
const htmlTemplate = new HtmlWebpackPlugin({template:'./src/index.html',favicon: './public/favicon.png'})
const config = {
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'bundle.[hash:4].js'
    },
    module:{
        rules:[
            {  
                test: /\.(woff|eot|ttf|svg|png|jpg)$/,  
                use: [  
                    {  
                        loader: 'url-loader',  
                        options: {  
                            limit: '1024' ,
                            name: '[name].[hash:4].[ext]'  
                        }                        
                    },  
                ]  
            },
            {  
                test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
                use: [  
                    {  
                        loader: 'url-loader',  
                        options: {  
                            limit: '1024',
                            name: '[name].[hash:4].[ext]'  
                        }  
                    },  
                ]  
            },
            {
                test: /\.(css|less)$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ["css-loader","less-loader"]
                })
            },
            {
                test:/\.(js|jsx)$/,
                use:"babel-loader",
                exclude:/node_modules/
            }
        ]
    },
}

module.exports = {
    htmlTemplate,
    extractCss,
    config
}
複製程式碼
  1. 重構開發環境配置
    修改開發環境的webpack.config.js
const path = require('path')
const baseConfig = require('./webpack.base')

module.exports = {
    entry:{
        main:['babel-polyfill','./src/index.js'],
    },
    ...baseConfig.config,
    plugins:[
        baseConfig.htmlTemplate,
        baseConfig.extractCss
    ],
    devServer:{
        contentBase: path.join(__dirname, "dist"),
        compress: true,
        port: 9000,
        proxy: {
            "/api": {
              target: "http://127.0.0.1:3000/",
              pathRewrite: {"^/api" : ""}
            }
          }
    }
}
複製程式碼
  1. 重構生產環境配置
    修改開發環境的webpack.pro.config.js
const webpack = require('webpack')
const baseConfig = require('./webpack.base')

module.exports = {
    entry:{
        main:['babel-polyfill','./src/index.js'],
        // 將第三方庫包單獨打包,充分利用瀏覽器快取        
        vendors: ['react','react-dom','react-router-dom','whatwg-fetch']
    },
    ...baseConfig.config,
    devtool: false,
    plugins:[
        // html 模板外掛
        baseConfig.htmlTemplate,
        // 啟用作用域提升,讓程式碼檔案更小、執行的更快
        new webpack.optimize.ModuleConcatenationPlugin(),
        // 提取公共程式碼vendors
        new webpack.optimize.CommonsChunkPlugin({
            name:'vendors',
            filename:'[name].[hash:4].js'
        }),
        // 抽離出css
        baseConfig.extractCss,
        // 壓縮js程式碼
        new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false,
                drop_console: true,
                pure_funcs: ['console.log']
            }
        }),
        // 定義全域性常量
        new webpack.DefinePlugin({
            "process.env": {
                "NODE_ENV": JSON.stringify("production")
            }
        }),
        // 加署名
        new webpack.BannerPlugin('Copyright by Zero https://github.com/l-Lemon/blog')
    ]
}
複製程式碼

好了,現在我們再來試試npm run devnpm run build命令,沒問題都可以完美執行。

總結


這篇文章我們介紹了生產環境webpack的配置,並且抽出了公共配置,重構了開發環境和生產環境的配置。

下篇我們來介紹實現單元測試

系列文章


  1. 從零開始React專案架構(一)
  2. 從零開始React專案架構(二)
  3. 從零開始React專案架構(三)

原始碼


React專案架構

相關文章