相關(guān)文章和閱讀順序
搭建Typescript+React項(xiàng)目模板(1) --- 項(xiàng)目初始化
搭建 Typescript+React 項(xiàng)目模板 (2) --- 提升開發(fā)體驗(yàn)
搭建 Typescript+React 項(xiàng)目模板 (3) --- 整理項(xiàng)目和雜項(xiàng)
搭建 Typescript+React 項(xiàng)目模板 (4) --- 項(xiàng)目打包
搭建 Typescript+React 項(xiàng)目模板 (5) --- 團(tuán)隊(duì)規(guī)范
文章已同步更新到掘金專欄(https://juejin.im/user/5a77c815f265da4e9518bebc/posts)
項(xiàng)目地址
前言
經(jīng)過前面的初始化,提升開發(fā)體驗(yàn)和集成了一堆工具耙考,調(diào)整了項(xiàng)目結(jié)構(gòu)等等之后谜喊,我們是時(shí)候考慮進(jìn)行項(xiàng)目打包了。
在這篇博客中倦始,我們不考慮開發(fā)環(huán)境和生產(chǎn)環(huán)境的配置分別斗遏,我們只看打包需要進(jìn)行的配置項(xiàng),所以我們需要做的如下:
- 添加打包路徑工具
- 添加打包命令
- 進(jìn)行css和js分離
- 修改
html-webpack-plugin
配置項(xiàng) - 添加
react-loadable
和react-router
,進(jìn)行代碼分離和按需加載 - 添加optimization,進(jìn)行第三方庫(kù)代碼分離
- 進(jìn)行代碼壓縮
- 關(guān)于
externals
添加打包命令
我們先去webpack.config.js
中觀察一下output
這個(gè)配置項(xiàng):
該配置項(xiàng)指定了打包路徑和打包后的js文件名鞋邑,在
webpack
的配置項(xiàng)中诵次,output
是必須有的。接著我們?nèi)サ?code>package.json中在
script
中添加打包命令build
枚碗,該命令引用我們的webpack.config.js
配置文件:之后試試運(yùn)行
npm run build
逾一,會(huì)發(fā)現(xiàn)已經(jīng)將項(xiàng)目打包出來了:添加打包路徑工具
在上一步中,我們已經(jīng)知道打包出來的文件位于根目錄下的dist
文件夾中肮雨,所以這個(gè)路徑工具的添加指向dist
文件夾:
我們?nèi)サ?code>build/utils.js文件中遵堵,添加如下代碼:
以后指定打包文件存放路徑的時(shí)候就可以直接使用這個(gè)工具進(jìn)行指定。
分離css文件
在上面打包的結(jié)果中酷含,我們會(huì)發(fā)現(xiàn)只有一個(gè)app.js
文件鄙早,而實(shí)際上我們是有寫css樣式的,但是現(xiàn)在的卻并沒有這個(gè)css文件椅亚,這是因?yàn)?code>webpack將所有的資源(包含js
, css
等等)都看成是chunk
限番,然后一起打包進(jìn)一個(gè)文件中,這樣會(huì)導(dǎo)致打包出來的js文件體積巨大呀舔,從而拖累頁面的加載速度弥虐。
- 在
webpack 4+
版本中扩灯,我們可以使用mini-css-extract-plugin
進(jìn)行css代碼的分離,所以首先安裝它npm install -D mini-css-extract-plugin
霜瘪。 - 然后我們到
build/plugins.js
中添加這個(gè)插件:
- 最后需要注意珠插,之前在提升開發(fā)體驗(yàn)這一章中有提到過一點(diǎn),
style-loader
用于將css-loader
編譯出來的代碼轉(zhuǎn)為js代碼并寫入js文件中颖对,所以在這里捻撑,我們需要用mini-css-extract-plugin
中的loader去替換掉style-loader
,讓它寫入單獨(dú)的css文件而不是js文件中:
我們?nèi)サ?code>build/rules/styleRules.js中缤底,將原本的style-loader
全都替換成mini-css-extract-plugin
的loader(這一步可以進(jìn)行開發(fā)環(huán)境和生產(chǎn)環(huán)境的區(qū)分顾患,在文章中不進(jìn)行區(qū)分):
- 經(jīng)過上面的步驟,我們可以打包進(jìn)行測(cè)試:
運(yùn)行npm run build
可以發(fā)現(xiàn)打包結(jié)果中css文件已經(jīng)進(jìn)行了分離:
而在打包出來的index.html
中也可以發(fā)現(xiàn)這個(gè)css文件被引入了:
-
最后我們?cè)僭诖虬窂街袑⒋虬鰜淼膉s文件用js文件夾包裹起來即可:
修改html-webpack-plugin
配置項(xiàng)
這一步主要用于壓縮打包出來的index.html
文件个唧,但是單頁面應(yīng)用的話html
內(nèi)容其實(shí)不多江解,所以做不做也差不多,在本文章中也只是做個(gè)介紹:
- 首先在
html-webpack-plugin
中利用的是html-minifier來做壓縮工作的徙歼,所以詳細(xì)配置點(diǎn)擊進(jìn)去看即可犁河,常用的如下:
- 第二個(gè)需要提一下則是
inject
這個(gè)配置項(xiàng),該項(xiàng)指定資源如何注入魄梯,我們直接使用默認(rèn)的true
即可桨螺,他會(huì)將js資源注入到<body>
標(biāo)簽的底部,如果要注入到頭部填寫head
即可
添加react-loadable
和react-router
,進(jìn)行代碼分離和按需加載
這一步和下一步都是在進(jìn)行代碼的拆分画恰,考慮的是如果所有文件都塞進(jìn)一個(gè)js文件中彭谁,會(huì)導(dǎo)致這個(gè)js文件體積臃腫吸奴,而單頁面應(yīng)用的所有構(gòu)建又是依賴于這個(gè)js文件允扇,所以需要進(jìn)行代碼分離,只加載當(dāng)前頁面需要構(gòu)建的js文件则奥。
通常來說考润,我們會(huì)根據(jù)react-router
分的頁面來進(jìn)行代碼分離,再用react-loadable進(jìn)行分割出來的代碼的異步加載(當(dāng)然你也可以將所有組件都進(jìn)行代碼分離然后異步加載)读处。
所以在這里我們先利用react-router
分兩個(gè)頁面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
進(jìn)行組件按需加載:
當(dāng)然不要忘了使用react-hot-loader
:
這一步需要注意的是,Loadable
這個(gè)函數(shù)中的loading參數(shù)是必須有的罚舱,至于如何使用可以自行參考react-loadable
的github鏈接井辜。 - 這個(gè)時(shí)候去到頁面看一下:
在/
路徑下,沒有加載page.js
這個(gè)文件管闷,而切換到/page
路徑則會(huì)加載page.js
文件粥脚,這個(gè)時(shí)候按需加載就完成了:
-
最后我們觀察一下打包后的js文件可以發(fā)現(xiàn)已經(jīng)進(jìn)行了分離:
會(huì)用optimization
進(jìn)行第三方庫(kù)代碼分離
optimization
是webpack4+版本中新出的配置項(xiàng),這個(gè)配置項(xiàng)的功能主要是進(jìn)行代碼壓縮包个,優(yōu)化刷允。
在本節(jié)中,我們需要將用到的處于node_modules
中的第三方代碼進(jìn)行分離,在這里主要用到的是兩個(gè)配置項(xiàng)optimization.runtimeChunk
和optimization.splitChunks
树灶,其中runtimeChunk
用于生成維系各各代碼塊關(guān)系的代碼纤怒,splitChunks
則用于指定需要進(jìn)行分塊的代碼,和分塊后文件名天通。
- 我們?nèi)サ?code>build目錄下泊窘,新建
optimization.js
,并添加如下代碼:
然后在webpack.config.js
中引入這個(gè)配置:
- 最后我們打包試試看可以發(fā)現(xiàn)第三方代碼都被打包進(jìn)
vendor.js
文件中了:
你可以通過比對(duì)在添加optimization
之前和之后打包出來的app.js
文件來看出效果像寒。
進(jìn)行代碼壓縮
在這一步中州既,我們主要是做js和css的代碼壓縮和優(yōu)化
- 在上面階段中,我們打包出來的js代碼是已經(jīng)經(jīng)過壓縮的:
所以在這個(gè)階段我們可以利用uglifyjs-webpack-plugin進(jìn)行一些壓縮優(yōu)化:
首先我們需要安裝npm install -D uglifyjs-webpack-plugin
萝映,然后去到build/optimization.js
中添加如下代碼即可吴叶,具體的優(yōu)化見代碼:
PS: 這里有一個(gè)點(diǎn)需要注意,在uglifyjs-webpack-plugin
這個(gè)插件中序臂,如果是2.x版本的話是不支持es6規(guī)范的蚌卤,所以建議安裝1.x版本,而我這里的版本是:
- 然后我們進(jìn)行css代碼的壓縮奥秆,這里需要使用到optimize-css-assets-webpack-plugin插件:
npm install -D optimize-css-assets-webpack-plugin
逊彭。
我們先去Home
組件中隨意添加一個(gè)樣式并使用它:
然后再去到build/optimization.js
添加如下代碼:
具體的插件使用方式可以自行上github查看該插件。
最后查看打包出來后的css代碼:
到現(xiàn)在壓縮代碼步驟也做完了构订,最后將介紹一下webpack.externals
這個(gè)選項(xiàng)侮叮。
關(guān)于externals
webpack.externals配置項(xiàng)用于在構(gòu)建過程中忽略一些常用包的集成,從而降低構(gòu)建時(shí)間和打包后的包大小悼瘾,它的配置也很簡(jiǎn)單囊榜,在本章中只做簡(jiǎn)單介紹:
在本項(xiàng)目中,我們可以將react
和react-dom
添加進(jìn)externals
中亥宿,然后在html模板中引入它們的外部鏈接:
- 我們先去到
webpack.config.js
中卸勺,添加externals
選項(xiàng),并且把react
和react-dom
添加進(jìn)去:
這個(gè)配置項(xiàng)接收的是一個(gè)對(duì)象(其他形式請(qǐng)自行查閱webpack文檔)烫扼,對(duì)象的鍵是指webapck在獲取這個(gè)模塊時(shí)候require
時(shí)候的參數(shù)曙求,而對(duì)應(yīng)的值則是標(biāo)明你打算將這個(gè)模塊掛載的變量名,這里是掛載在window對(duì)象中的映企。 - 去到
build/tpl/index.html
中悟狱,引入cdn中react
和react-dom
的鏈接:
- 重啟項(xiàng)目,可以發(fā)現(xiàn)在
npm run dev
中能夠正常使用堰氓,并且也已經(jīng)引入了兩者的外部資源:
-
最后我們來對(duì)比一下打包后模塊占用情況:
再來對(duì)比一下兩者打包出來的包體積大小: