對(duì) CSS 工程化的理解
對(duì) CSS 工程化的理解
CSS 工程化是為了解決以下問(wèn)題:
宏觀設(shè)計(jì):CSS 代碼如何組織、如何拆分、模塊結(jié)構(gòu)怎樣設(shè)計(jì)?
編碼優(yōu)化:怎樣寫(xiě)出更好的 CSS?
構(gòu)建:如何處理我的 CSS,才能讓它的打包結(jié)果最優(yōu)?
可維護(hù)性:代碼寫(xiě)完了,如何最小化它后續(xù)的變更成本?如何確保任何一個(gè)同事都能輕松接手?
以下三個(gè)方向都是時(shí)下比較流行的、普適性非常好的 CSS 工程化實(shí)踐:
1.預(yù)處理器:Less、 Sass 等;
2.重要的工程化插件: PostCss;
3.Webpack loader 等 。
基于這三個(gè)方向,可以衍生出一些具有典型意義的子問(wèn)題,這里我們逐個(gè)來(lái)看:
(1)預(yù)處理器:為什么要用預(yù)處理器?它的出現(xiàn)是為了解決什么問(wèn)題?
預(yù)處理器,其實(shí)就是 CSS 世界的“輪子”。預(yù)處理器支持我們寫(xiě)一種類(lèi)似 CSS、但實(shí)際并不是 CSS 的語(yǔ)言,然后把它編譯成 CSS 代碼:

那為什么寫(xiě) CSS 代碼寫(xiě)得好好的,偏偏要轉(zhuǎn)去寫(xiě)“類(lèi) CSS”呢?這就和本來(lái)用 JS 也可以實(shí)現(xiàn)所有功能,但最后卻寫(xiě) React 的 jsx 或者 Vue 的模板語(yǔ)法一樣——為了爽!要想知道有了預(yù)處理器有多爽,首先要知道的是傳統(tǒng) CSS 有多不爽。隨著前端業(yè)務(wù)復(fù)雜度的提高,前端工程中對(duì) CSS 提出了以下的訴求:
1.宏觀設(shè)計(jì)上:我們希望能優(yōu)化 CSS 文件的目錄結(jié)構(gòu),對(duì)現(xiàn)有的 CSS 文件實(shí)現(xiàn)復(fù)用;
2.編碼優(yōu)化上:我們希望能寫(xiě)出結(jié)構(gòu)清晰、簡(jiǎn)明易懂的 CSS,需要它具有一目了然的嵌套層級(jí)關(guān)系,而不是無(wú)差別的一鋪到底寫(xiě)法;我們希望它具有變量特征、計(jì)算能力、循環(huán)能力等等更強(qiáng)的可編程性,這樣我們可以少寫(xiě)一些無(wú)用的代碼;
3.可維護(hù)性上:更強(qiáng)的可編程性意味著更優(yōu)質(zhì)的代碼結(jié)構(gòu),實(shí)現(xiàn)復(fù)用意味著更簡(jiǎn)單的目錄結(jié)構(gòu)和更強(qiáng)的拓展能力,這兩點(diǎn)如果能做到,自然會(huì)帶來(lái)更強(qiáng)的可維護(hù)性。
這三點(diǎn)是傳統(tǒng) CSS 所做不到的,也正是預(yù)處理器所解決掉的問(wèn)題。預(yù)處理器普遍會(huì)具備這樣的特性:
1.嵌套代碼的能力,通過(guò)嵌套來(lái)反映不同 css 屬性之間的層級(jí)關(guān)系 ;
2.支持定義 css 變量;
3.提供計(jì)算函數(shù);
4.允許對(duì)代碼片段進(jìn)行 extend 和 mixin;
5.支持循環(huán)語(yǔ)句的使用;
6.支持將 CSS 文件模塊化,實(shí)現(xiàn)復(fù)用。
(2)PostCss:PostCss 是如何工作的?我們?cè)谑裁磮?chǎng)景下會(huì)使用 PostCss?

它和預(yù)處理器的不同就在于,預(yù)處理器處理的是 類(lèi) CSS,而 PostCss 處理的就是 CSS 本身。Babel 可以將高版本的 JS 代碼轉(zhuǎn)換為低版本的 JS 代碼。PostCss 做的是類(lèi)似的事情:它可以編譯尚未被瀏覽器廣泛支持的先進(jìn)的 CSS 語(yǔ)法,還可以自動(dòng)為一些需要額外兼容的語(yǔ)法增加前綴。更強(qiáng)的是,由于 PostCss 有著強(qiáng)大的插件機(jī)制,支持各種各樣的擴(kuò)展,極大地強(qiáng)化了 CSS 的能力。
PostCss 在業(yè)務(wù)中的使用場(chǎng)景非常多:
1.提高 CSS 代碼的可讀性:PostCss 其實(shí)可以做類(lèi)似預(yù)處理器能做的工作;
2.當(dāng)我們的 CSS 代碼需要適配低版本瀏覽器時(shí),PostCss 的 插件可以幫助我們自動(dòng)增加瀏覽器前綴;
3.允許我們編寫(xiě)面向未來(lái)的 CSS:PostCss 能夠幫助我們編譯 CSS next 代碼;
(3)Webpack 能處理 CSS 嗎?如何實(shí)現(xiàn)? Webpack 能處理 CSS 嗎:
1.Webpack 在裸奔的狀態(tài)下,是不能處理 CSS 的,Webpack 本身是一個(gè)面向 JavaScript 且只能處理 JavaScript 代碼的模塊化打包工具;
2.Webpack 在 loader 的輔助下,是可以處理 CSS 的。
如何用 Webpack 實(shí)現(xiàn)對(duì) CSS 的處理:
????Webpack 中操作 CSS 需要使用的兩個(gè)關(guān)鍵的 loader:css-loader 和 style-loader
????注意,答出“用什么”有時(shí)候可能還不夠,面試官會(huì)懷疑你是不是在背答案,所以你還需要了解每個(gè) loader 都做了什么事情:
????????css-loader:導(dǎo)入 CSS 模塊,對(duì) CSS 代碼進(jìn)行編譯處理;
????????style-loader:創(chuàng)建 style 標(biāo)簽,把 CSS 內(nèi)容寫(xiě)入標(biāo)簽。
在實(shí)際使用中,css-loader 的執(zhí)行順序一定要安排在 style-loader 的前面。因?yàn)橹挥型瓿闪司幾g過(guò)程,才可以對(duì) css 代碼進(jìn)行插入;若提前插入了未編譯的代碼,那么 webpack 是無(wú)法理解這坨東西的,它會(huì)無(wú)情報(bào)錯(cuò)。