相關文章和閱讀順序
專案地址
前言
經過前面的初始化,提升開發體驗和整合了一堆工具,調整了專案結構等等之後,我們是時候考慮進行專案打包了。
在這篇部落格中,我們不考慮開發環境和生產環境的配置分別,我們只看打包需要進行的配置項,所以我們需要做的如下:
0. 新增打包路徑工具
- 新增打包命令
- 進行css和js分離
- 修改
html-webpack-plugin
配置項 - 新增
react-loadable
和react-router
,進行程式碼分離和按需載入 - 新增optimization,進行第三方庫程式碼分離
- 進行程式碼壓縮
- 關於
externals
新增打包命令
我們先去webpack.config.js
中觀察一下output
這個配置項:
該配置項指定了打包路徑和打包後的js檔名,在webpack
的配置項中,output
是必須有的。
接著我們去到package.json
中在script
中新增打包命令build
,該命令引用我們的webpack.config.js
配置檔案:
之後試試執行npm run build
,會發現已經將專案打包出來了:
新增打包路徑工具
在上一步中,我們已經知道打包出來的檔案位於根目錄下的dist
資料夾中,所以這個路徑工具的新增指向dist
資料夾:
我們去到build/utils.js
檔案中,新增如下程式碼:
以後指定打包檔案存放路徑的時候就可以直接使用這個工具進行指定。
分離css檔案
在上面打包的結果中,我們會發現只有一個app.js
檔案,而實際上我們是有寫css樣式的,但是現在的卻並沒有這個css檔案,這是因為webpack
將所有的資源(包含js
, css
等等)都看成是chunk
,然後一起打包進一個檔案中,這樣會導致打包出來的js檔案體積巨大,從而拖累頁面的載入速度。
- 在
webpack 4+
版本中,我們可以使用mini-css-extract-plugin
進行css程式碼的分離,所以首先安裝它npm install -D mini-css-extract-plugin
。 - 然後我們到
build/plugins.js
中新增這個外掛:
- 最後需要注意,之前在提升開發體驗這一章中有提到過一點,
style-loader
用於將css-loader
編譯出來的程式碼轉為js程式碼並寫入js檔案中,所以在這裡,我們需要用mini-css-extract-plugin
中的loader去替換掉style-loader
,讓它寫入單獨的css檔案而不是js檔案中:
我們去到build/rules/styleRules.js
中,將原本的style-loader
全都替換成mini-css-extract-plugin
的loader(這一步可以進行開發環境和生產環境的區分,在文章中不進行區分): - 經過上面的步驟,我們可以打包進行測試:
執行npm run build
可以發現打包結果中css檔案已經進行了分離:而在打包出來的
index.html
中也可以發現這個css檔案被引入了: - 最後我們再在打包路徑中將打包出來的js檔案用js資料夾包裹起來即可:
修改html-webpack-plugin
配置項
這一步主要用於壓縮打包出來的index.html
檔案,但是單頁面應用的話html
內容其實不多,所以做不做也差不多,在本文章中也只是做個介紹:
- 首先在
html-webpack-plugin
中利用的是html-minifier來做壓縮工作的,所以詳細配置點選進去看即可,常用的如下:
- 第二個需要提一下則是
inject
這個配置項,該項指定資源如何注入,我們直接使用預設的true
即可,他會將js資源注入到<body>
標籤的底部,如果要注入到頭部填寫head
即可
新增react-loadable
和react-router
,進行程式碼分離和按需載入
這一步和下一步都是在進行程式碼的拆分,考慮的是如果所有檔案都塞進一個js檔案中,會導致這個js檔案體積臃腫,而單頁面應用的所有構建又是依賴於這個js檔案,所以需要進行程式碼分離,只載入當前頁面需要構建的js檔案。
通常來說,我們會根據react-router
分的頁面來進行程式碼分離,再用react-loadable進行分割出來的程式碼的非同步載入(當然你也可以將所有元件都進行程式碼分離然後非同步載入)。
所以在這裡我們先利用react-router
分兩個頁面home
和page
出來:
- 首先我們安裝
react-router
:
npm install -S react-router-dom
,然後在src/containers/views
中新建Home
和Page
元件: - 接著安裝
react-loadable
:
npm install -S react-loadable
, 然後在src/containers/shared
中新建App
元件:之後在裡面的
index.tsx
中引用react-router
和react-loadable
進行元件按需載入:
當然不要忘了使用react-hot-loader
:這一步需要注意的是,
Loadable
這個函式中的loading引數是必須有的,至於如何使用可以自行參考react-loadable
的github連結。 - 這個時候去到頁面看一下:
在/
路徑下,沒有載入page.js
這個檔案,而切換到/page
路徑則會載入page.js
檔案,這個時候按需載入就完成了: - 最後我們觀察一下打包後的js檔案可以發現已經進行了分離:
會用optimization
進行第三方庫程式碼分離
optimization
是webpack4+版本中新出的配置項,這個配置項的功能主要是進行程式碼壓縮,優化。
在本節中,我們需要將用到的處於node_modules
中的第三方程式碼進行分離,在這裡主要用到的是兩個配置項optimization.runtimeChunk
和optimization.splitChunks
,其中runtimeChunk
用於生成維繫各各程式碼塊關係的程式碼,splitChunks
則用於指定需要進行分塊的程式碼,和分塊後檔名。
- 我們去到
build
目錄下,新建optimization.js
,並新增如下程式碼:
然後在
webpack.config.js
中引入這個配置: - 最後我們打包試試看可以發現第三方程式碼都被打包進
vendor.js
檔案中了:
你可以通過比對在新增
optimization
之前和之後打包出來的app.js
檔案來看出效果。
進行程式碼壓縮
在這一步中,我們主要是做js和css的程式碼壓縮和優化
- 在上面階段中,我們打包出來的js程式碼是已經經過壓縮的:
所以在這個階段我們可以利用uglifyjs-webpack-plugin進行一些壓縮優化:
首先我們需要安裝npm install -D uglifyjs-webpack-plugin
,然後去到build/optimization.js
中新增如下程式碼即可,具體的優化見程式碼:PS: 這裡有一個點需要注意,在
uglifyjs-webpack-plugin
這個外掛中,如果是2.x版本的話是不支援es6規範的,所以建議安裝1.x版本,而我這裡的版本是: - 然後我們進行css程式碼的壓縮,這裡需要使用到optimize-css-assets-webpack-plugin外掛:
npm install -D optimize-css-assets-webpack-plugin
。
我們先去Home
元件中隨意新增一個樣式並使用它:然後再去到
build/optimization.js
新增如下程式碼:具體的外掛使用方式可以自行上github檢視該外掛。
最後檢視打包出來後的css程式碼:
到現在壓縮程式碼步驟也做完了,最後將介紹一下webpack.externals
這個選項。
關於externals
webpack.externals配置項用於在構建過程中忽略一些常用包的整合,從而降低構建時間和打包後的包大小,它的配置也很簡單,在本章中只做簡單介紹:
在本專案中,我們可以將react
和react-dom
新增進externals
中,然後在html模板中引入它們的外部連結:
- 我們先去到
webpack.config.js
中,新增externals
選項,並且把react
和react-dom
新增進去:
這個配置項接收的是一個物件(其他形式請自行查閱webpack文件),物件的鍵是指webapck在獲取這個模組時候
require
時候的引數,而對應的值則是標明你打算將這個模組掛載的變數名,這裡是掛載在window物件中的。 - 去到
build/tpl/index.html
中,引入cdn中react
和react-dom
的連結:
- 重啟專案,可以發現在
npm run dev
中能夠正常使用,並且也已經引入了兩者的外部資源:
- 最後我們來對比一下打包後模組佔用情況:
再來對比一下兩者打包出來的包體積大小: