咱們在上一篇一步步學Webpack4(1)-- 開發環境搭建入門中使用Webpack完成了開發環境搭建的入門實戰練習,此次咱們來學習如何配置生產環境.css
本章按照分離配置 - 減小打包體積 - 提供基本調試支持
的步驟進行:html
當前項目中已經有一個 webpack.config.js
配置文件而且運行良好,可是這個配置只適用於開發環境, 開發環境和生產環境的項目構建目標不同.webpack
開發環境的構建目標是具有方便問題追溯的source-map & 修改保存代碼以後的實時加載或者熱模塊更新,一切爲方便開發服務; 生產環境的構建目標更可能是經過生成更小的打包文件、更輕的source map、最優化的資源利用,最終實現加載時間的優化.爲了在開發環境與生產環境都達到最優的效果,官方文檔建議爲環境編寫獨立的配置.git
雖說開發環境與生產環境將會被分離,可是他們仍是一部分配置能夠通用的. 依據DRY原則(Don‘t repeat yourself), 咱們將保留一份通用配置,並藉助 webpack-merge
在特定環境配置中調用通用配置.github
步驟1、安裝:webpack-mergeweb
npm install --save-dev webpack-merge
在項目根目錄添加 webpack.commom.js
、webpack.dev.js
、webpack.prod.js
三個文件, 將webpack.config.js
拆解放入三個文件中,文件的完整代碼以下所示:npm
webpack.commom.jsjson
const path = require("path"); const CleanWebpackPlugin = require('clean-webpack-plugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = { entry: { app: './src/index.js' }, output: { filename: 'main.js', path: path.resolve(__dirname, 'dist') }, plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ inject: false, template: 'index.html', filename: 'index.html' }) ], module: { rules: [ { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(png|svg|jpg|gif)$/, use: [ 'file-loader' ] }, { test: /\.(woff|woff2|eot|ttf|otf)$/, use: [ 'file-loader' ] }, { test: /\.xml$/, use: [ 'xml-loader' ] } ] } }
webpack.dev.jssegmentfault
const merge = require('webpack-merge'); const common = require('./webpack.common'); const webpack = require('webpack'); module.exports = merge( common, { devtool: 'inline-source-map', devServer: { contentBase: './dist', hot: true }, plugins: [ new webpack.HotModuleReplacementPlugin() ] });
webpack.prod.js架構
const merge = require('webpack-merge'); const common = require('webpack.common.js'); module.exports = merge(common, { // 暫無配置 });
npm start
運行webpack-dev-server; 開始打包準備發佈時,運行 npm build
運行webpack.{ "name": "webpack-stepbystep", "version": "1.0.0", "description": "", "private": true, "scripts": { "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "clean-webpack-plugin": "^0.1.19", "css-loader": "^1.0.0", "csv-loader": "^3.0.2", "file-loader": "^2.0.0", "html-webpack-plugin": "^3.2.0", "style-loader": "^0.23.1", "webpack": "^4.23.0", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.10", "webpack-merge": "^4.1.4", "xml-loader": "^1.2.1" }, "dependencies": { "lodash": "^4.17.11" } }
雖然項目配置架構與腳本已經完成,可是生產環境的配置仍是空白的.生產環境配置的須要實現的基本功能有:
想要知道完成生產配置以後的效果,須要源文件不變,經過對比修改生產配置文件以後的結果來驗證. 因而咱們先爲 print.js
添加一個 」不被調用「 的方法模塊,看看最終有沒有方法能夠更好地優化代碼.添加模塊以後的完整代碼以下所示:
print.js
export default function printMe () { console.log('Updating print.js'); } export function printTest () { console.log('Testing'); }
爲了接下來編譯的時候代碼不被壓縮,因此暫時將webpack的配置改成 mode: 'development'
, 完整配置以下所示:
webpack.prod.js
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'development' });
在終端輸入 npm run build
,根據當前 webpack.prod.js
完成打包,結果以下所示:
雖然代碼沒有引用 printTest
模塊,可是 mode: development
模式下的打包文件仍是包含了該模塊. 編譯完的js打包文件 main.js
大小竟然達到了575kb,引用了一個lodash庫和一個printMe模塊就半M了...
接着讀官方文檔Tree Shaking, 瞭解到一個叫作搖樹(Tree Shaking)的概念,官方給出的理解方法是:
意思就是把應用當成一棵樹,那些真正被調用的源代碼和庫是長在樹上的綠色葉子,那些沒有被調用的庫和代碼就是已經枯死的葉子,你能夠經過搖晃這顆樹把樹上的枯葉搖下來,也就是說應用裏沒用到的代碼和庫能夠經過「搖樹」移除.
回想一下上次打包的結果,統一文件的未被調用模塊代碼也被打包到打包的js文件中,那麼也就意味着loadsh庫也是這樣被打包的,那麼咱們如今要作的事情就是實現「搖樹「,移除Webpack構建的依賴關係圖中無用的代碼和庫.
官方文檔的Tree Shaking和Production說得讓人頭大 (而且脫髮) , 說了挺多搖樹和生產環境的東西可是讓人無從下手,直到我看到 Miniication
小節的這一句:
而後查了相關資料後我才發現,其實在Webpack4以後的Webpack已經自帶壓縮和「搖樹」了,只要將 webpack.prod.js
的 mode: 'development'
改成 mode: 'production'
,完整代碼以下所示:
webpack.prod.js
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'production' });
打包完成以後的 main.js
只剩下77kb了,壓縮了至少80%吧,而且裏面已經移除了沒有調用的模塊,成功完成減小文件體積的需求:
官方建議在生產環境開啓source map,理由是對於調試以及應用評分有幫助. 配置起來也是十分簡單, 只須要加入一行 devtool: 'source-map'
:
webpack.prod.js
const merge = require('webpack-merge'); const common = require('./webpack.common.js'); module.exports = merge(common, { mode: 'production', devtool: 'source-map' });
在看看打包結果,發現打包後原來全部文件大小不變,可是多出了一個700kb的map文件,作哦那個應該就是生產環境中映射源代碼吧,生產環境對於基本調試的支持也成功實現了:
至今生產環境的基本配置已經所有完成
To be continued...