相關文章和閱讀順序
專案地址
前言
經過前面的初始化,提升開發體驗和整合了一堆工具,調整了專案結構等等之後,我們是時候考慮進行專案打包了。 在這篇部落格中,我們不考慮開發環境和生產環境的配置分別,我們只看打包需要進行的配置項,所以我們需要做的如下: 0. 新增打包路徑工具
- 新增打包命令
- 進行css和js分離
- 修改
html-webpack-plugin
配置項 - 新增
react-loadable
和react-router
,進行程式碼分離和按需載入 - 新增optimization,進行第三方庫程式碼分離
- 進行程式碼壓縮
- 關於
externals
新增打包命令
我們先去webpack.config.js
中觀察一下output
這個配置項:
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
中能夠正常使用,並且也已經引入了兩者的外部資源: - 最後我們來對比一下打包後模組佔用情況: 再來對比一下兩者打包出來的包體積大小: