Webpack配置區分開發環境和生產環境

  • 2019 年 10 月 3 日
  • 筆記

  在項目開發的時候,我們通常會將程式分為開發環境和生產環境(或者叫線上環境),開發環境通常指的是我們正在開發的這個階段所需要的一些環境配置,也就是方便我們開發人員調試開發的一種環境;生產環境通常指的是我們將程式開發完成經過測試之後無明顯異常準備發布上線的環境,也可以理解為用戶可以正常使用的就是生產環境;

  當然開發環境和生產環境在配置方面的需求是不一樣的,但是有共同點:

  開發環境的需求:

    模組熱更新  (本地開啟服務,實時更新)
    sourceMap    (方便打包調試)
    介面代理     (配置proxyTable解決開發環境中的跨域問題)

    程式碼規範檢查 (程式碼規範檢查工具)

  生產環境的需求:

    提取公共程式碼        
    壓縮混淆(壓縮混淆程式碼,清除程式碼空格,注釋等資訊使其變得難以閱讀)
    文件壓縮/base64編碼(壓縮程式碼,減少線上環境文件包的大小)
    去除無用的程式碼

 

  開發環境和生產環境的共同需求:

    同樣的入口
    同樣的程式碼處理(loader處理)
    同樣的解析配置

 

    在我們搭建好Vue-cli腳手架之後,我們的build文件夾會分別自動的生成webpack.base.conf.js、webpack.dev.conf.js、webpack.prod.conf.js三個webpack配置文件;

    webpack.base.conf.js:webpack的開發環境和生產環境的共有配置(開發環境和生產環境都是需要執行的配置)

    webpack.dev.conf.js:webpack的開發環境的特有配置(只在開發環境中執行,生產環境中不執行)

    webpack.prod.conf.js:webpack的生產環境的特有配置(只在生產環境中執行,開發環境中不執行)

 

    我們為什麼要區分開發環境和生產環境呢?

      因為一個項目的開發過程中肯定不會是一個版本開發完之後就立馬上線,開發是必需,上線是目的;在開發的過程中會有各種各樣的問題,比如開發環境中跨域、開發環境和生產環境因環境不同而產生的未知奇葩錯誤等等都是會時常發生的,我們區分環境的目的就是為了讓開發人員在開發的過程中可以方便調試,保持高效的開發;讓程式在生產環境中正常有效的運行;

    

 

    webpack.base.conf.js配置

    

const path = require('path');  //清除build/dist文件夾文件  const CleanWebpackPlugin = require('clean-webpack-plugin');  //生成創建Html入口文件  const HtmlWebpackPlugin = require('html-webpack-plugin');  //將css提取到單獨的文件中  const MiniCssExtract = require('mini-css-extract-plugin');  //css壓縮  const OptimizeCss = require('optimize-css-assets-webpack-plugin');  //壓縮js文件  const UglifyJsPlugin = require('uglifyjs-webpack-plugin');  //引入webpack  const webpack = require('webpack');    module.exports = {  //webpack 入口文件      entry: './src/index.js',  //webpack 輸出文件配置      output: {      //輸出文件路徑          path: path.resolve(__dirname, 'dist'),     //輸出文件名          filename: 'k-editor.[hash:8].js',      },    //配置插件      plugins: [      //使用插件清除dist文件夾中的文件          new CleanWebpackPlugin({              path: './dist'          }),      //使用插件生成Html入口文件          new HtmlWebpackPlugin({           //模板文件路徑              template: "./src/index.html",          //模板文件名              filename: "index.html",              minify: {                  removeAttributeQuotes: true, //刪除雙引號,                  collapseWhitespace: true,    //壓縮成一行,              },              hash: true          }),        //提取css到style.css中          new MiniCssExtract({              filename: 'style.css'          }),      ],      resolve: {          // modules: [path.resolve('node_modules')],//只在當前目錄下查找          alias: { //別名              'bootstrap': 'bootstrap/dist/css/bootstrap.css',          },          // mainFields: ['style', 'main'],//優先尋找style,          // mainFiles: [],//入口文件的名字,默認index.js          // extensions: ['js', 'css', 'json', 'vue']//擴展名順序      },     //loader載入器模組配置      module: {          rules: [              {              //正則表達式匹配.css為後綴的文件                  test: /.css$/,             //使用loader                  use: [                      MiniCssExtract.loader,                      'css-loader',                      {                          loader: "postcss-loader"                      },                  ]           //正則表達式匹配.less為後綴的文件           //使用lodaer來處理              }, {                  test: /.less$/,                  use: [                      MiniCssExtract.loader,                      'css-loader',                      {                          loader: "postcss-loader"                      },                      'less-loader'                  ]              },              /* {                   test: /.js$/,                 //不包括node_modules                   exclude: /node_modules/,                   use: [{                       loader: "eslint-loader",                       options: {                           enforce: 'pre'    //強制更改順序,pre 前  post 後                       }                   }],               },*/              {                  test: /.js$/,  //普通的loader                 //不包括node_modules                  exclude: /node_modules/,                  use: [{                      loader: "babel-loader"                  }]              },              {                  test: /.html$/,                  use: ['html-withimg-loader']              },              {                  test: /.(gif|png|jpg)$/,                  use: [{                      loader: "url-loader",                      options: {               //圖片小於10kb就是圖片地址,大於正常打包成base64格式編碼                              limit: 10000,                         //輸出路徑                          outputPath: 'img/'                      }                  }]              }          ]      },  };

 

  webpack.dev.conf.js:

  

//引入webpack-merge插件進行合併  const {merge} = require('webpack-merge');  //引入webpack.base.conf.js文件  const base = require('./webpack.base.conf');  //引入webpack  const webpack = require('webpack');  //進行合併,將webpack.base.conf.js中的配置合併到這  module.exports = merge(base, {     //模組參數      mode: 'development',      devServer: {          contentBase: './dist',        //埠號          port: '8383',          inline: true,          historyApiFallback: true,//在開發單頁應用時非常有用,它依賴於HTML5 history API,如果設置為true,所有的跳轉將指向index.html          hot: true//允許熱載入      },  //啟用source-map方便調試      devtool: 'source-map',      plugins: [         //定義全局變數          new webpack.DefinePlugin({           //這裡必須要解析成字元串進行判斷,不然將會被識別為一個變數              DEV: JSON.stringify('dev')          })      ]  });

  webpack.prod.conf.js:

 

const {merge} = require('webpack-merge');  const base = require('./webpack.base');    const path = require('path');  const OptimizeCss = require('optimize-css-assets-webpack-plugin');  const UglifyJsPlugin = require('uglifyjs-webpack-plugin');  const webpack = require('webpack');    module.exports = merge(base, {      mode: 'production',      optimization: {          minimizer: [            //壓縮CSS程式碼              new OptimizeCss(),            //壓縮js程式碼              new UglifyJsPlugin({                //啟用文件快取                  cache: true,               //使用多執行緒並行運行提高構建速度                  parallel: true,               //使用 SourceMaps 將錯誤資訊的位置映射到模組                  sourceMap: true              })          ]      },      plugins:[       //使用插件定義全局變數DEV          new webpack.DefinePlugin({              DEV:JSON.stringify('production')          })      ]    });

 

  最後在配置一下package.json文件就可以了:

  

"scripts": {      "test": "npm  run test",      "dev": "webpack-dev-server --config webpack.dev.js",      "build": "webpack --config webpack.prod.js"    },

   

    如何區分開發環境和生產環境呢?

      在node中,我們有一個對象process對象,它裡面包括的一些資訊,env和它的一些屬性,當然NODE_ENV是我們自己加上去的自定義屬性,用來區分環境變數,也就是通過這個變數來進行區別是開發環境還是生產環境;但是有個問題,不同電腦上設置的方式是不一樣的,所以cross-env就來了,它可以跨平台設置環境和使用環境變數。

    

npm install cross-env

   我們在webpack.base.conf.js文件中修改程式碼:

const NODE_ENV=process.env.NODE_ENV;  console.log(NODE_ENV);

 

     然後我們修改package.json文件:

//--config是可以設置我們執行哪個webpack文件,默認是執行webpack.config.js,但是我們現在修改文件名了,所以我們要設置一下  "build": "cross-env NODE_ENV=production webpack --config webpack.config.prod.js",  "dev": "cross-env NODE_ENV=development webpack-dev-server --config webpack.config.dev.js"

 

  就這樣,我們就實現了利用webpack來區分開發環境和生產環境,當我們用npm run dev運行的時候就是開發環境,當我們運行npm run build的時候就是構建生產環境打包;

 

 對了,最後再多說一句,從今天開始,本文作者的個人微信公眾號正式開通(公眾號已接入第七代微軟小冰AI機器人),後期文章微信公眾號將同步更新,如果覺得文章對你有幫助,可以掃碼關注一下:

  

Tags: