搭建Typescript+React項(xiàng)目模板(4) --- 項(xiàng)目打包

相關(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),所以我們需要做的如下:

  1. 添加打包路徑工具
  2. 添加打包命令
  3. 進(jìn)行css和js分離
  4. 修改html-webpack-plugin配置項(xiàng)
  5. 添加react-loadablereact-router,進(jìn)行代碼分離和按需加載
  6. 添加optimization,進(jìn)行第三方庫(kù)代碼分離
  7. 進(jìn)行代碼壓縮
  8. 關(guān)于externals

添加打包命令

我們先去webpack.config.js中觀察一下output這個(gè)配置項(xiàng):

image.png

該配置項(xiàng)指定了打包路徑和打包后的js文件名鞋邑,在webpack的配置項(xiàng)中诵次,output是必須有的。
接著我們?nèi)サ?code>package.json中在script中添加打包命令build枚碗,該命令引用我們的webpack.config.js配置文件:
image.png

之后試試運(yùn)行npm run build逾一,會(huì)發(fā)現(xiàn)已經(jīng)將項(xiàng)目打包出來了:
image.png

添加打包路徑工具

在上一步中,我們已經(jīng)知道打包出來的文件位于根目錄下的dist文件夾中肮雨,所以這個(gè)路徑工具的添加指向dist文件夾:
我們?nèi)サ?code>build/utils.js文件中遵堵,添加如下代碼:

image.png

以后指定打包文件存放路徑的時(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文件體積巨大呀舔,從而拖累頁面的加載速度弥虐。

  1. webpack 4+版本中扩灯,我們可以使用mini-css-extract-plugin進(jìn)行css代碼的分離,所以首先安裝它npm install -D mini-css-extract-plugin霜瘪。
  2. 然后我們到build/plugins.js中添加這個(gè)插件:
    image.png
  3. 最后需要注意珠插,之前在提升開發(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ū)分):
    image.png

    image.png
  4. 經(jīng)過上面的步驟,我們可以打包進(jìn)行測(cè)試:
    運(yùn)行npm run build可以發(fā)現(xiàn)打包結(jié)果中css文件已經(jīng)進(jìn)行了分離:
    image.png

    而在打包出來的index.html中也可以發(fā)現(xiàn)這個(gè)css文件被引入了:
    image.png
  5. 最后我們?cè)僭诖虬窂街袑⒋虬鰜淼膉s文件用js文件夾包裹起來即可:


    image.png

    image.png

修改html-webpack-plugin配置項(xiàng)

這一步主要用于壓縮打包出來的index.html文件个唧,但是單頁面應(yīng)用的話html內(nèi)容其實(shí)不多江解,所以做不做也差不多,在本文章中也只是做個(gè)介紹:

  1. 首先在html-webpack-plugin中利用的是html-minifier來做壓縮工作的徙歼,所以詳細(xì)配置點(diǎn)擊進(jìn)去看即可犁河,常用的如下:
    image.png
  2. 第二個(gè)需要提一下則是inject這個(gè)配置項(xiàng),該項(xiàng)指定資源如何注入魄梯,我們直接使用默認(rèn)的true即可桨螺,他會(huì)將js資源注入到<body>標(biāo)簽的底部,如果要注入到頭部填寫head即可

添加react-loadablereact-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è)頁面homepage出來:

  1. 首先我們安裝react-router:
    npm install -S react-router-dom糊治,然后在src/containers/views中新建HomePage組件:
    image.png

    image.png

    image.png
  2. 接著安裝react-loadable:
    npm install -S react-loadable, 然后在src/containers/shared中新建App組件:
    image.png

    之后在里面的index.tsx中引用react-routerreact-loadable進(jìn)行組件按需加載:
    當(dāng)然不要忘了使用react-hot-loader:
    image.png

    這一步需要注意的是,Loadable這個(gè)函數(shù)中的loading參數(shù)是必須有的罚舱,至于如何使用可以自行參考react-loadable的github鏈接井辜。
  3. 這個(gè)時(shí)候去到頁面看一下:
    /路徑下,沒有加載page.js這個(gè)文件管闷,而切換到/page路徑則會(huì)加載page.js文件粥脚,這個(gè)時(shí)候按需加載就完成了:
    image.png

    image.png
  4. 最后我們觀察一下打包后的js文件可以發(fā)現(xiàn)已經(jīng)進(jìn)行了分離:


    image.png

會(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.runtimeChunkoptimization.splitChunks树灶,其中runtimeChunk用于生成維系各各代碼塊關(guān)系的代碼纤怒,splitChunks則用于指定需要進(jìn)行分塊的代碼,和分塊后文件名天通。

  1. 我們?nèi)サ?code>build目錄下泊窘,新建optimization.js,并添加如下代碼:
    image.png

    然后在webpack.config.js中引入這個(gè)配置:
    image.png
  2. 最后我們打包試試看可以發(fā)現(xiàn)第三方代碼都被打包進(jìn)vendor.js文件中了:
    image.png

    你可以通過比對(duì)在添加optimization之前和之后打包出來的app.js文件來看出效果像寒。

進(jìn)行代碼壓縮

在這一步中州既,我們主要是做js和css的代碼壓縮和優(yōu)化

  1. 在上面階段中,我們打包出來的js代碼是已經(jīng)經(jīng)過壓縮的:
    image.png

    所以在這個(gè)階段我們可以利用uglifyjs-webpack-plugin進(jìn)行一些壓縮優(yōu)化:
    首先我們需要安裝npm install -D uglifyjs-webpack-plugin萝映,然后去到build/optimization.js中添加如下代碼即可吴叶,具體的優(yōu)化見代碼:
    image.png

    PS: 這里有一個(gè)點(diǎn)需要注意,在uglifyjs-webpack-plugin這個(gè)插件中序臂,如果是2.x版本的話是不支持es6規(guī)范的蚌卤,所以建議安裝1.x版本,而我這里的版本是:
    image.png
  2. 然后我們進(jìn)行css代碼的壓縮奥秆,這里需要使用到optimize-css-assets-webpack-plugin插件:npm install -D optimize-css-assets-webpack-plugin逊彭。
    我們先去Home組件中隨意添加一個(gè)樣式并使用它:
    image.png

    image.png

    然后再去到build/optimization.js添加如下代碼:
    image.png

    具體的插件使用方式可以自行上github查看該插件。
    最后查看打包出來后的css代碼:
    image.png

到現(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)目中,我們可以將reactreact-dom添加進(jìn)externals中亥宿,然后在html模板中引入它們的外部鏈接:

  1. 我們先去到webpack.config.js中卸勺,添加externals選項(xiàng),并且把reactreact-dom添加進(jìn)去:
    image.png

    這個(gè)配置項(xiàng)接收的是一個(gè)對(duì)象(其他形式請(qǐng)自行查閱webpack文檔)烫扼,對(duì)象的鍵是指webapck在獲取這個(gè)模塊時(shí)候require時(shí)候的參數(shù)曙求,而對(duì)應(yīng)的值則是標(biāo)明你打算將這個(gè)模塊掛載的變量名,這里是掛載在window對(duì)象中的映企。
  2. 去到build/tpl/index.html中悟狱,引入cdn中reactreact-dom的鏈接:
    image.png
  3. 重啟項(xiàng)目,可以發(fā)現(xiàn)在npm run dev中能夠正常使用堰氓,并且也已經(jīng)引入了兩者的外部資源:
    image.png
  4. 最后我們來對(duì)比一下打包后模塊占用情況:


    不使用externals

    使用externals

    再來對(duì)比一下兩者打包出來的包體積大小:


    不使用externals

    使用externals
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末挤渐,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子豆赏,更是在濱河造成了極大的恐慌挣菲,老刑警劉巖富稻,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異白胀,居然都是意外死亡椭赋,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門或杠,熙熙樓的掌柜王于貴愁眉苦臉地迎上來哪怔,“玉大人,你說我怎么就攤上這事向抢∪暇常” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵挟鸠,是天一觀的道長(zhǎng)叉信。 經(jīng)常有香客問我,道長(zhǎng)艘希,這世上最難降的妖魔是什么硼身? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮覆享,結(jié)果婚禮上佳遂,老公的妹妹穿的比我還像新娘。我一直安慰自己撒顿,他們只是感情好丑罪,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著凤壁,像睡著了一般吩屹。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上客扎,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天祟峦,我揣著相機(jī)與錄音罚斗,去河邊找鬼徙鱼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛针姿,可吹牛的內(nèi)容都是我干的袱吆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼距淫,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绞绒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起榕暇,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤蓬衡,失蹤者是張志新(化名)和其女友劉穎喻杈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狰晚,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡筒饰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了壁晒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓷们。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖秒咐,靈堂內(nèi)的尸體忽然破棺而出谬晕,到底是詐尸還是另有隱情,我是刑警寧澤携取,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布攒钳,位于F島的核電站,受9級(jí)特大地震影響雷滋,放射性物質(zhì)發(fā)生泄漏夕玩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一惊豺、第九天 我趴在偏房一處隱蔽的房頂上張望燎孟。 院中可真熱鬧,春花似錦尸昧、人聲如沸揩页。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爆侣。三九已至,卻和暖如春幢妄,著一層夾襖步出監(jiān)牢的瞬間兔仰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工蕉鸳, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留乎赴,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓潮尝,卻偏偏與公主長(zhǎng)得像榕吼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子勉失,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容