相關(guān)文章和閱讀順序
搭建Typescript+React項目模板(1) --- 項目初始化
搭建 Typescript+React 項目模板 (2) --- 提升開發(fā)體驗
搭建 Typescript+React 項目模板 (3) --- 整理項目和雜項
搭建 Typescript+React 項目模板 (4) --- 項目打包
搭建 Typescript+React 項目模板 (5) --- 團隊規(guī)范
文章已同步更新到掘金專欄(https://juejin.im/user/5a77c815f265da4e9518bebc/posts)
項目地址
前言
本章主要介紹的是建立在項目初始化的基礎(chǔ)上如何優(yōu)化開發(fā)體驗
內(nèi)容包含如下:
- 支持
sass - 支持
css module - 配置公用的
sass屬性 - 支持裝飾器
- 路徑優(yōu)化
- 構(gòu)建緩存
- 構(gòu)建加速
支持sass
什么是sass
sass是一款css預(yù)處理語言,支持變量,嵌套,mixin和導(dǎo)入等功能,可以極大地方便和簡化css寫法。支持sass
支持sass首先需要安裝sass-loader和node-sass
npm install -D node-sass sass-loader
另外還需要安裝style-loader和css-loader
npm install -D style-loader css-loader-
配置webpack
在這里有一個點是需要注意的,因為將sass代碼編譯成可用的樣式代碼需要用到三個loader,所以就會產(chǎn)生順序問題,首先sass-loader將sass代碼編譯為css(默認(rèn)使用node-sass),然后css-loader將編譯出來的代碼再次編譯成為符合CommonJS的代碼,最后style-loader將第二步編譯出來的代碼轉(zhuǎn)為js代碼,然后webpack進(jìn)行l(wèi)oader編譯的順序是從下到上的:
知道上面的順序后我們在webpack中的配置就非常簡單了,直接在module.rules下面加上.scss文件類型的編譯配置即可:
image.png -
查看效果
這時候我們在src下面新建一個index.scss,然后在index.tsx里面引入這個文件查看效果
目錄結(jié)構(gòu)
index.tsx
index.scss
效果如圖:
image.png
支持css module
什么是
css module
css module是針對css類名作用域做出限定的一種規(guī)范,用以解決css類名沖突的問題,此外還能避免一些爬蟲進(jìn)行數(shù)據(jù)爬取(當(dāng)然厲害的爬蟲除外),同等的還有BEM規(guī)范。安裝對應(yīng)的包
因為在這里我們用的是TypeScript,所以可以用typings-for-css-modules-loader這個包,這個包也可以替代css-loader的功能,此外這個包還能根據(jù).scss文件里面的類名自動生成對應(yīng)的.d.ts文件:
npm install -D typings-for-css-modules-loader-
配置webpack
這個配置接非常簡單了,因為要用typings-for-css-modules-loader替代css-loader的功能,所以直接替換即可,將前面sass的配置修改為如下:
image.png -
使用和問題
這個時候我們將index.tsx文件修改為如下:
image.png
修改為這樣既可,但是同時我們也發(fā)現(xiàn)一個問題:
image.png
這個問題導(dǎo)致的原因是因為.scss文件中并沒有類似export這樣的關(guān)鍵詞用于導(dǎo)出一個模塊,所以也就導(dǎo)致報錯找不到模塊,這個問題可以通過ts的模塊聲明(declare module)來解決。 -
解決模塊聲明問題
這時候我們在根目錄下新建一個typings文件夾,用于存放.scss的模塊聲明,以及后續(xù)需要用到的全局校驗接口,然后新建typed-css-modules.d.ts文件用于存放.scss模塊聲明,目錄結(jié)構(gòu)和聲明內(nèi)容如下:
image.png -
效果
這個時候回到index.tsx文件中你會發(fā)現(xiàn)錯誤標(biāo)紅消失了,然后我們在index.scss文件中新增如下代碼
image.png
保存后你會發(fā)現(xiàn)當(dāng)前目錄下新增了一個index.scss.d.ts文件,打開里面可以發(fā)現(xiàn)是針對每個類名的類型校驗,當(dāng)以后新增類名的時候,typed-css-modules.d.ts都會自動在index.scss.d.ts里面新增對應(yīng)的類型校驗:
image.png
這時候回到頁面查看,你會發(fā)現(xiàn)類名變成了一個hash值,這樣可以有效地避免類名全局污染問題:
image.png
配置公共sass屬性
既然已經(jīng)可以使用sass進(jìn)行更加簡便的css代碼編寫,那么我們也可以將常用的一些樣式代碼和sass變量寫入公共文件中,當(dāng)使用的時候就可以直接引入使用,這可以提高一定的效率節(jié)約時間:
-
新建公共樣式目錄
首先在src目錄下新建styles文件夾,然后在styles文件夾下新建var.scss文件用于存放樣式變量。
之后在var.scss文件里寫入一個顏色變量和一個樣式:
image.png -
查看效果
然后在index.scss文件里面引入var.scss,接著就可以直接使用里面的變量了:
image.png
效果:
image.png -
優(yōu)化
上面的效果其實已經(jīng)達(dá)成,但還是存在一個不好的問題,就是在引入var.scss的路徑上要根據(jù)每個文件夾的路徑相對來引入非常麻煩,那么我們能否做到只需要@import var.scss就行呢?答案是可以的,我們可以使用一個node-sass的屬性includePaths進(jìn)行路徑優(yōu)化:
image.png
image.png
支持裝飾器
-
前置工作
在src目錄下新建一個components文件夾,用于存放通用組件,然后在components文件及里面新建一個組件Test,然后在網(wǎng)頁入口引入這個組件,如下圖所示:
image.png
image.png -
什么是裝飾器,為什么需要裝飾器
裝飾器本質(zhì)上就是一個函數(shù),這個函數(shù)對類(class)本身進(jìn)行一些處理,也可以將裝飾器的寫法當(dāng)做一種語法糖,如果不用裝飾器的話,可以寫成下圖這樣:
image.png
但是如果裝飾器多的話就會變成如下樣子:
image.png
這樣會導(dǎo)致代碼非常難以理解,于是裝飾器就登上舞臺了。這在今后使用了mobx(or redux)的時候也是非常有用的。 -
設(shè)置裝飾器可用
根據(jù)裝飾器的語法,我們可以將上面的代碼寫成如下:
image.png
但是你會發(fā)現(xiàn)這里報了一個錯誤,這是因為裝飾器語法在es6標(biāo)準(zhǔn)中還只是一個提案,并未正式支持,但是在ts中,裝飾器已經(jīng)被正式支持了,不用ts的可以自行安裝babel相關(guān)包進(jìn)行支持。
image.png
那么怎么解決這個錯誤呢?我們根據(jù)錯誤提示進(jìn)入到tsconfig文件中,將experimentalDecorators設(shè)置為true即可,然后回到頁面查看log裝飾器已經(jīng)生效了:
image.png
優(yōu)化路徑
- 為什么
在上面的例子中我們新建了components文件夾,然后在入口處引入了其中的Test組件
image.png
但是這時候需要考慮到一個問題,如果以后在一個層級比較深的文件中引入這個組件會不會產(chǎn)生如下這種情況呢?
import Test from '../../../../components/Test'
這樣不僅書寫起來麻煩還容易出錯,因此這時候就需要進(jìn)行一些路徑上的優(yōu)化,使得無論在哪個地方引入這些組件都能用同一種寫法,例如:
import Test from '@comonents/Test'
- 路徑優(yōu)化
這里針對路徑的優(yōu)化有兩種方案,第一種是直接在webpack.resolve.alias中進(jìn)行路徑配置:
image.png
但是在這里我們使用了ts,所以還需要在tsconfig中進(jìn)行配置:
image.png
這樣也能用,不過我們還可以用tsconfig-paths-webpack-plugin這個包將tsconfig中對路徑的設(shè)置映射到webpack配置中去,這樣就不需要在webpack中再進(jìn)行一次路徑的配置了,首先安裝:
npm install -D tsconfig-paths-webpack-plugin
然后就采用前面tsconfig里面對baseUrl和paths的配置。
之后進(jìn)入webpack配置中,引入tsconfig-paths-webpack-plugin
image.png
接著在webpack.resolve中新增配置項plugins(這里要注意的是新增的不是webpack.plugins,而是webpack.resolve.plugins),配置如下代碼:
image.png
接著我們就可以愉快地使用簡化后的路徑了:
image.png
構(gòu)建緩存
什么是構(gòu)建緩存
我們一般會使用webpack-dev-server來進(jìn)行項目開發(fā),當(dāng)我們運行webpack-dev-server的時候它會在內(nèi)存中進(jìn)行項目的構(gòu)建,但是當(dāng)使用了babel之類的代碼轉(zhuǎn)換工具后,會對項目構(gòu)建產(chǎn)生較大的性能影響,這是因為每一次的構(gòu)建都會對代碼進(jìn)行重新轉(zhuǎn)換。
而構(gòu)建緩存就是將構(gòu)建的公用代碼緩存在磁盤上,這樣做的效果就是第一次構(gòu)建的時間花銷會比不用緩存的構(gòu)建大,但是在之后每次構(gòu)建的時間花銷都會大大減少。-
對比
我們拿一個較大的項目來看區(qū)別。
注: 左邊是沒有設(shè)置構(gòu)建緩存,右邊進(jìn)行了構(gòu)建緩存。
首先進(jìn)行對比的是第一次構(gòu)建時候的時間花銷:
image.png
然后是第二次構(gòu)建的時間花銷:
image.png
可以看出在第二次構(gòu)建的時候時間花銷減少了百分之五十以上。 設(shè)置構(gòu)建緩存
在設(shè)置構(gòu)建緩存之前我們首先要考慮的是那些地方需要進(jìn)行設(shè)置,那么在前面的配置過程中,可以看出花銷較大的地方有對ts(x)的轉(zhuǎn)換并且以后還會添加對應(yīng)的babel進(jìn)去,然后還有針對sass類型的轉(zhuǎn)換,那么我們就先對這兩個地方的轉(zhuǎn)換進(jìn)行配置
- 對ts(x)的轉(zhuǎn)換
這里因為我們使用的是awesome-typescript-loader,這個庫本身自帶了開啟緩存的選項useCache,然后我們需要指定一個保存緩存文件的地方cacheDirectory,所以配置改為如下:
image.png - 對
sass類型的轉(zhuǎn)換
這個地方我們需要使用到一個庫cache-loader
npm install -D cache-loader,
然后在對.scss文件類型的轉(zhuǎn)換配置中使用它,在這里我們主要是針對轉(zhuǎn)換出來的css進(jìn)行緩存,所以需要寫在typings-for-css-modules-loader配置的前面:
image.png
這樣就配置好當(dāng)前的構(gòu)建緩存了,當(dāng)你npm run dev的時候會發(fā)現(xiàn)根目錄下生成了緩存文件.cache-loader。
image.png
打開它看會發(fā)現(xiàn)有對應(yīng)的緩存代碼:
image.png
不過現(xiàn)在只是根據(jù)目前需要進(jìn)行的緩存配置,當(dāng)后面集成antd等相關(guān)庫的時候因為需要使用到less類型,所以以后還需要根據(jù)需要進(jìn)行添加。
此外,在構(gòu)建這方面的知識在后面的項目打包部分也是非常有用的。



































