以前自己寫一小項目時,webpack的配置基本就是一套配置,沒有考慮生產環境和開發環境的區分,最近在做一個復雜的商城項目接觸到了webpack的高級配置,經過兩天的研究,寫出了一份目前來說比叫滿意的配置,在這里分享一下。
如何區分開發環境和生產環境?
眾所周知,webpack時基于node.js平臺運行的,要區分開發環境和生產環境還要存,node入手。我們啟動webpack時,都需要輸入一些命令,npm run 、yarn start之類的,所以我們就從命令行入手,告訴webpack,當前是什么環境。
package.json
{  "name": "webpac-demo",  "version": "1.0.0",  "description": "webpack練習",  "main": "index.js",  "scripts": {    //配置開發環境參數。注意:真實開發中 package.json 文件中不能有注釋    "dev": "webpack --env=development",    //配置生產環境參數    "dist": "webpack --env=production",    "start": "webpack-dev-server --env=development"  },  "dependencies": {    "font-awesome": "^4.7.0",    "react": "^16.2.0",    "react-dom": "^16.2.0"  },  "devDependencies":{  ...  }}這樣配置,當我們在命令行輸入 npm run dev 和 npm run dist 時,就會附帶一些參數到命令行中,有了參數,我們該如何拿到呢?那就要用到 node 的一個命令行參數解析引擎了。
minimist
minimist輕量級的命令行參數解析引擎
// test.jsvar args = require('minimist')(process.argv.slice(2));console.log(args.hello);$ node test.js --env=production// production$ node test.js --env=development// development$ node test.js --env// true 注意:不是空字符串而是trueminimist會把參數解析成一個JSON對象:{key:value},有了這個JSON對象,我們就可以知道,當前的命令是要執行開發打包,還是生產打包了。
// webpack.config.jsconst webpack = require('webpack');//當前項目的絕對路勁const path = require('path');// 命令行參數解析引擎const argv = require('minimist')(process.argv.slice(2));let env = null;switch (argv.env) {  case 'production':    //生產環境配置文件名     env = 'webpack.config.prod';    break;  default:    //開發環境配置文件名     env = 'webpack.config.dev';}console.log(`當前是 ${argv.env} 打包`);// 這時候,我們就可以加載相應的wabpack配置了。module.exports = require( path.resolve( '加載的配置文件路勁',env ) );webpack開發環境配置和生產環境配置
開發環境配置
在開發環境下,我們首先考慮的是方便開發,方便代碼調試,不需要考慮代碼合并和css樣式分離這些。
這里主要說三個 :1.css模塊化;2.模塊熱替換功能;3.source-map(代碼映射)
// 開發環境打包配置const path = require('path');const webpack = require('webpack');const base = require('./webpack.config.base')const dfPath = require('./path')// webpack配置合并工具const merge =require('webpack-merge')const RS = (...arg)=>path.resolve( __dirname , ...arg )// 合并方式配置let strategyMerge = merge.strategy({  entry: 'prepend'});let config = {  entry: {    app: path.resolve(dfPath.root,'src/app.js')  },  output: {    path: dfPath.dist,    filename: '[name].bundle.js',    publicPath: '/',    chunkFilename: '[name].sepChunk.js'  },  module:{    rules: [      {        test: //.js$/,        use:['babel-loader'],        exclude: [          dfPath.node_modules        ]      },      {        test://.css$/,        use:[          'style-loader',          {            loader:'css-loader',            options:{              // css模塊化,方便多人開發              module:true,              // 定義模塊化css后的類名(默認為hash值,可讀性差)path:路勁; name:文件名; local:本地定義的className              localIdentName: '[path][name]__[local]--[hash:base64:5]'            },          }        ],        // 排除的文件,遇到這些文件不會用當前 loader 處理,也就不會模塊化        exclude:[          RS('./src/common'),                   RS('node_modules')        ]      },      {        test://.css$/,        use:['style-loader','css-loader'],        include:[          RS('./src/common'),                   RS('node_modules')        ]              },                  {        test: //.(png|jpg|jpeg|gif)$/,        use: ['url-loader?limit=8192'],      }    ]  },  plugins:[    // 模塊熱替換功能    new webpack.HotModuleReplacementPlugin()  ],    // 代碼映射,方便報錯時,找到對應的源代碼  devtool: 'cheap-module-eval-source-map',  devServer:{    // 服務器打包后,輸出的資源路勁    publicPath:'/',    open:true  }};// 導出合并后的webpack配置module.exports = strategyMerge( base , config );生產環境配置
相比開發環境,生產環境打包是要最后發布到服務器部署的代碼,我們需要盡量保持代碼簡潔,加載性能最優,不需要調試輔助工具。
我們從這幾個方面優化 :1.公共模塊拆分,單獨打包;2. css文件分離,單獨打包輸出;3.代碼壓縮;
// 生產環境配置const webpack = require('webpack');const base = require('./webpack.config.base')const path = require('path');const dfPath = require('./path');const merge = require('webpack-merge');// 壓縮工具const ClosureCompilerPlugin = require('webpack-closure-compiler');// css單獨打包插件const extractTextWebpackPlugin = require('extract-text-webpack-plugin');const extractCSS = new extractTextWebpackPlugin('assets/css/[name]_[contenthash:6].css');// weback合并配置let strategyMerge = merge.strategy({  entry: 'replace',  output: 'replace',  module:{    rules: 'replace'  }});let config ={  entry: {    // 公共模塊拆分,這些代碼會單獨打包,一般我們會把引用的框架文件拆分出來,方便瀏覽器緩存,節省資源。    vender:['react'],    app: path.resolve(dfPath.root,'src/app.js')  },    output: {    path: dfPath.dist,    filename: 'assets/js/[name]_[chunkhash].bundle.js',    publicPath: '/',    chunkFilename: 'assets/js/[name].sepChunk.js',    hashDigestLength: 6  },  module:{    rules: [      {        test: //.js$/,        use:['babel-loader'],        exclude: [          dfPath.node_modules        ]      },      /* 開啟 css單獨打包 和 css模塊化的配置 */       {        test: //.css$/,        use: extractCSS.extract({          use: [            {              loader: 'css-loader',              options:{                modules: true              }                          }          ]        })      },           {        test: //.(png|jpg|jpeg|gif)$/,        use: [          {            loader: 'url-loader',            options:{              limit:8192,              name: '[name]_[hash].[ext]',              outputPath: 'assets/img/'            }          }        ],      },            {        test: //.(mp4|ogg|svg|ico)$/,        use: [          {            loader: 'file-loader',            options:{              name: '[name]_[hash].[ext]',              outputPath: 'assets/media/'            }          }        ]      },      {        test: //.(woff|woff2)(/?v=/d+/./d+/./d+)?$/,        use: [          {            loader: 'url-loader',            options:{              limit:10000,              name: '[name]_[hash].[ext]',              outputPath: 'assets/font/',              mimetype: 'application/font-woff'            }          }        ]      },      {        test: //.ttf(/?v=/d+/./d+/./d+)?$/,        use: [          {            loader: 'url-loader',            options:{              limit:10000,              name: '[name]_[hash].[ext]',              outputPath: 'assets/font/',              mimetype: 'application/octet-stream'            }          }        ]      },      {        test: //.eot(/?v=/d+/./d+/./d+)?$/,        use: [          {            loader: 'file-loader',            options:{              name: '[name]_[hash].[ext]',              outputPath: 'assets/font/',            }          }        ]      },      {        test: //.svg(/?v=/d+/./d+/./d+)?$/,        use: [          {            loader: 'url-loader',            options:{              limit:10000,              name: '[name]_[hash].[ext]',              outputPath: 'assets/font/',              mimetype: 'image/svg+xml'            }          }        ]      },    ]  },  plugins:[    extractCSS,        // 設置 process.env(生產環境) 環境變量的快捷方式。    new webpack.EnvironmentPlugin({      NODE_ENV: 'production'    })        ,new ClosureCompilerPlugin()  ],  devtool: 'source-map'};module.exports = strategyMerge(base,config);以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。
新聞熱點
疑難解答