<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          CSS工程化

          共 12226字,需瀏覽 25分鐘

           ·

          2021-03-01 23:48

          ????

          db79b846b42c8ee08d843c8ecce92238.webp


          人生不止有技術(shù)
          ?鏈接每一位開發(fā)者,讓編程更有趣兒!關(guān)注

          css的問題

          類名沖突的問題

          當(dāng)你寫一個(gè)css類的時(shí)候,你是寫全局的類呢?還是寫多個(gè)層級(jí)選擇后的類呢?

          你會(huì)發(fā)現(xiàn),怎么都不好!

          • 過深的層級(jí)不利于編寫、閱讀、壓縮、復(fù)用

          • 過淺的層級(jí)容易導(dǎo)致類名沖突

          一旦樣式多起來,這個(gè)問題就會(huì)變得越發(fā)嚴(yán)重,其實(shí)歸根結(jié)底,就是類名沖突不好解決的問題。

          重復(fù)樣式

          這種問題就更普遍了,一些重復(fù)的樣式值總是不斷的出現(xiàn)在css代碼中,維護(hù)起來極其困難。

          比如,一個(gè)網(wǎng)站的顏色一般就那么幾種:

          • primary
          • info
          • warn
          • error
          • success 如果有更多的顏色,都是從這些色調(diào)中自然變化得來,可以想象,這些顏色會(huì)到處充斥到諸如背景、文字、邊框中,一旦要做顏色調(diào)整,是一個(gè)非常大的工程。

          css文件細(xì)分問題

          在大型項(xiàng)目中,css也需要更細(xì)的拆分,這樣有利于css代碼的維護(hù)。

          比如,有一個(gè)做輪播圖的模塊,它不僅需要依賴js功能,還需要依賴css樣式,既然依賴的js功能僅關(guān)心輪播圖,那css樣式也應(yīng)該僅關(guān)心輪播圖,由此類推,不同的功能依賴不同的css樣式、公共樣式可以單獨(dú)抽離,這樣就形成了不同于過去的css文件結(jié)構(gòu):文件更多、拆分的更細(xì)

          而同時(shí),在真實(shí)的運(yùn)行環(huán)境下,我們卻希望文件越少越好,這種情況和JS遇到的情況是一致的,因此,對(duì)于css,也需要工程化管理。

          從另一個(gè)角度來說,css的工程化會(huì)遇到更多的挑戰(zhàn),因?yàn)閏ss不像JS,它的語法本身經(jīng)過這么多年并沒有發(fā)生多少的變化(css3也僅僅是多了一些屬性而已),對(duì)于css語法本身的改變也是一個(gè)工程化的課題

          如何解決

          這么多年來,官方一直沒有提出方案來解決上述問題,一些第三方機(jī)構(gòu)針對(duì)不同的問題,提出了自己的解決方案。

          解決類名沖突

          一些第三方機(jī)構(gòu)提出了一些方案來解決該問題,常見的解決方案如下:

          「命名約定」

          就是提供一種命名的標(biāo)準(zhǔn),來解決沖突,常見的標(biāo)準(zhǔn)有:

          • BEM
          • OOCSS
          • AMCSS
          • SMACSS
          • 其他

          我主要以BEM為例說下:

          BEM是一套針對(duì)css類樣式的命名方法。其他命名方法還有:OOCSS、AMCSS、SMACSS等等

          BEM全稱是:Block Element Modifier

          一個(gè)完整的BEM類名:block__element_modifier,例如:banner__dot_selected,可以表示:輪播圖中,處于選中狀態(tài)的小圓點(diǎn)

          80d7fc2669331ecd943d4f2cb8453b76.webp

          三個(gè)部分的具體含義為:

          • Block :頁(yè)面中的大區(qū)域,表示最頂級(jí)的劃分,例如:輪播圖(banner)、布局(layout)、文章(article)等等

          • element :區(qū)域中的組成部分,例如:輪播圖中的橫幅圖片(banner__img)、輪播圖中的容器(banner__container)、布局中的頭部(layout__header)、文章中的標(biāo)題(article__title)

          • modifier :可選。通常表示狀態(tài),例如:處于展開狀態(tài)的布局左邊欄(layout__left_expand)、處于選中狀態(tài)的輪播圖小圓點(diǎn)(banner__dot_selected) 在某些大型工程中,如果使用BEM命名法,還可能會(huì)增加一個(gè)前綴,來表示類名的用途,常見的前綴有:

          • l : layout,表示這個(gè)樣式是用于布局的

          • c : component,表示這個(gè)樣式是一個(gè)組件,即一個(gè)功能區(qū)域

          • u : util,表示這個(gè)樣式是一個(gè)通用的、工具性質(zhì)的樣式

          • j : javascript,表示這個(gè)樣式?jīng)]有實(shí)際意義,是專門提供給js獲取元素使用的

          「css in js」

          這個(gè)方案賊大膽,它覺得,css語言本身幾乎無可救藥了,干脆直接用js對(duì)象來表示樣式,然后把樣式直接應(yīng)用到元素的style中

          這樣一來,css變成了一個(gè)一個(gè)的對(duì)象,就可以完全利用到j(luò)s語言的優(yōu)勢(shì),你可以:

          • 通過一個(gè)函數(shù)返回一個(gè)樣式對(duì)象
          • 把公共的樣式提取到公共模塊中返回
          • 應(yīng)用js的各種特性操作對(duì)象,比如:混合、提取、拆分
          • 更多的花樣 這種方案在手機(jī)端的React Native中大行其道

          css in js 的核心思想是:用一個(gè)JS對(duì)象來描述樣式,而不是css樣式表

          例如下面的對(duì)象就是一個(gè)用于描述樣式的對(duì)象:

          const?styles?=?{
          ????backgroundColor:?"#f40",
          ????color:?"#fff",
          ????width:?"400px",
          ????height:?"500px",
          ????margin:?"0?auto"
          }

          由于這種描述樣式的方式根本就不存在類名,自然不會(huì)有類名沖突

          至于如何把樣式應(yīng)用到界面上,不是它所關(guān)心的事情,你可以用任何技術(shù)、任何框架、任何方式將它應(yīng)用到界面。

          css in js 的特點(diǎn)

          • 絕無沖突的可能:由于它根本不存在類名,所以絕不可能出現(xiàn)類名沖突
          • 更加靈活:可以充分利用JS語言靈活的特點(diǎn),用各種招式來處理樣式
          • 應(yīng)用面更廣:只要支持js語言,就可以支持css in js,因此,在一些用JS語言開發(fā)移動(dòng)端應(yīng)用的時(shí)候非常好用,因?yàn)橐苿?dòng)端應(yīng)用很有可能并不支持css
          • 書寫不便:書寫樣式,特別是公共樣式的時(shí)候,處理起來不是很方便
          • 在頁(yè)面中增加了大量冗余內(nèi)容:在頁(yè)面中處理css in js時(shí),往往是將樣式加入到元素的style屬性中,會(huì)大量增加元素的內(nèi)聯(lián)樣式,并且可能會(huì)有大量重復(fù),不易閱讀最終的頁(yè)面代碼

          「css module」

          非常有趣和好用的css模塊化方案,編寫簡(jiǎn)單,絕對(duì)不重名

          通過命名規(guī)范來限制類名太過死板,而css in js雖然足夠靈活,但是書寫不便。 css module 開辟一種全新的思路來解決類名沖突的問題

          思路:

          css module 遵循以下思路解決類名沖突問題:

          1. css的類名沖突往往發(fā)生在大型項(xiàng)目中
          2. 大型項(xiàng)目往往會(huì)使用構(gòu)建工具(webpack等)搭建工程
          3. 構(gòu)建工具允許將css樣式切分為更加精細(xì)的模塊
          4. 同JS的變量一樣,每個(gè)css模塊文件中難以出現(xiàn)沖突的類名,沖突的類名往往發(fā)生在不同的css模塊文件中
          5. 只需要保證構(gòu)建工具在合并樣式代碼后不會(huì)出現(xiàn)類名沖突即可
          e5221e6ebfd00baf2208b6a50f287035.webp

          實(shí)現(xiàn)原理

          在webpack中,作為處理css的css-loader,它實(shí)現(xiàn)了css module的思想,要啟用css module,需要將css-loader的配置modules設(shè)置為true。

          css-loader的實(shí)現(xiàn)方式如下:

          d8fc740e8ee2dbf7735eb3a865de40bc.webp

          原理極其簡(jiǎn)單,開啟了css module后,css-loader會(huì)將樣式中的類名進(jìn)行轉(zhuǎn)換,轉(zhuǎn)換為一個(gè)唯一的hash值。

          由于hash值是根據(jù)模塊路徑和類名生成的,因此,不同的css模塊,哪怕具有相同的類名,轉(zhuǎn)換后的hash值也不一樣。

          2155ecdd03b2d87c87bef7673513eca7.webp

          如何應(yīng)用樣式:

          css module帶來了一個(gè)新的問題:源代碼的類名和最終生成的類名是不一樣的,而開發(fā)者只知道自己寫的源代碼中的類名,并不知道最終的類名是什么,那如何應(yīng)用類名到元素上呢?

          為了解決這個(gè)問題,css-loader會(huì)導(dǎo)出原類名和最終類名的對(duì)應(yīng)關(guān)系,該關(guān)系是通過一個(gè)對(duì)象描述的90de05c02c02db2560cf4ee429655f17.webp

          這樣一來,我們就可以在js代碼中獲取到css模塊導(dǎo)出的結(jié)果,從而應(yīng)用類名了

          style-loader為了我們更加方便的應(yīng)用類名,會(huì)去除掉其他信息,僅暴露對(duì)應(yīng)關(guān)系

          其他操作

          • 全局類名 某些類名是全局的、靜態(tài)的,不需要進(jìn)行轉(zhuǎn)換,僅需要在類名位置使用一個(gè)特殊的語法即可:
          :global(.main){
          ????...
          }

          使用了global的類名不會(huì)進(jìn)行轉(zhuǎn)換,相反的,沒有使用global的類名,表示默認(rèn)使用了local

          :local(.main){
          ????...
          }

          使用了local的類名表示局部類名,是可能會(huì)造成沖突的類名,會(huì)被css module進(jìn)行轉(zhuǎn)換

          • 如何控制最終的類名 絕大部分情況下,我們都不需要控制最終的類名,因?yàn)榭刂扑鼪]有任何意義

          如果一定要控制最終的類名,需要配置css-loader的localIdentName

          • 其他注意事項(xiàng)
          1. css module往往配合構(gòu)建工具使用
          2. css module僅處理頂級(jí)類名,盡量不要書寫嵌套的類名,也沒有這個(gè)必要
          3. css module僅處理類名,不處理其他選擇器
          4. css module還會(huì)處理id選擇器,不過任何時(shí)候都沒有使用id選擇器的理由
          5. 使用了css module后,只要能做到讓類名望文知意即可,不需要遵守其他任何的命名規(guī)范

          解決重復(fù)樣式的問題

          「css in js」

          這種方案雖然可以利用js語言解決重復(fù)樣式值的問題,但由于太過于激進(jìn),很多習(xí)慣寫css的開發(fā)者編寫起來并不是很適應(yīng)

          「css預(yù)編譯器」

          有些第三方搞出一套css語言的進(jìn)化版來解決這個(gè)問題,它支持變量、函數(shù)等高級(jí)語法,然后經(jīng)過編譯器將其編譯成為正常的css

          這種方案特別像構(gòu)建工具,不過它僅針對(duì)css

          常見的預(yù)編譯器支持的語言有:

          • less
          • sass

          基本原理

          編寫css時(shí),受限于css語言本身,常常難以處理一些問題:

          • 重復(fù)的樣式值:例如常用顏色、常用尺寸
          • 重復(fù)的代碼段:例如絕對(duì)定位居中、清除浮動(dòng)
          • 重復(fù)的嵌套書寫 由于官方遲遲不對(duì)css語言本身做出改進(jìn),一些第三方機(jī)構(gòu)開始想辦法來解決這些問題,其中一種方案,便是預(yù)編譯器。

          預(yù)編譯器的原理很簡(jiǎn)單,即使用一種更加優(yōu)雅的方式來書寫樣式代碼,通過一個(gè)編譯器,將其轉(zhuǎn)換為可被瀏覽器識(shí)別的傳統(tǒng)css代碼。

          032377b94662e666d0f65a9e5166f7a7.webp目前,最流行的預(yù)編譯器有LESS和SASS,它們兩個(gè)特別相似,這里主要說less1280aca42f8e6b02da83779cf7af0945.webp

          • less官網(wǎng):http://lesscss.org/
          • less中文文檔1(非官方):http://lesscss.cn/
          • less中文文檔2(非官方):https://less.bootcss.com/
          • sass官網(wǎng):https://sass-lang.com/
          • sass中文文檔1(非官方):https://www.sass.hk/
          • sass中文文檔2(非官方):https://sass.bootcss.com/

          LESS的安裝和使用

          從原理可知,要使用LESS,必須要安裝LESS編譯器

          LESS編譯器是基于node開發(fā)的,可以通過npm下載安裝

          npm?i?-D?less

          安裝好了less之后,它提供了一個(gè)CLI工具lessc,通過該工具即可完成編譯

          lessc?less代碼文件?編譯后的文件

          光說不練假把式:

          新建一個(gè)index.less文件,編寫內(nèi)容如下:

          //?less代碼
          @red:?#f40;

          .redcolor?{
          ????color:?@red;
          }

          運(yùn)行命令:

          lessc?index.less?index.css

          可以看到編譯之后的代碼:

          .redcolor?{
          ??color:?#f40;
          }

          LESS的基本使用

          具體的使用見文檔:https://less.bootcss.com/

          • 變量
          • 混合
          • 嵌套
          • 運(yùn)算
          • 函數(shù)
          • 作用域
          • 注釋
          • 導(dǎo)入

          「postcss」

          什么是PostCss?

          CSS工程化面臨著諸多問題,而解決這些問題的方案多種多樣。如果把CSS單獨(dú)拎出來看,光是樣式本身,就有很多事情要處理。

          既然有這么多事情要處理,何不把這些事情集中到一起統(tǒng)一處理呢?

          PostCss就是基于這樣的理念出現(xiàn)的。PostCss類似于一個(gè)編譯器,可以將樣式源碼編譯成最終的CSS代碼

          d997cb67a449f609c6783fc76fc3f7e2.webp看上去是不是和LESS、SASS一樣呢?

          但PostCss和LESS、SASS的思路不同,它其實(shí)只做一些代碼分析之類的事情,將分析的結(jié)果交給插件,具體的代碼轉(zhuǎn)換操作是插件去完成的。

          f3931b8afa401c09f47c82f4f75dbe09.webp

          官方的一張圖更能說明postcss的處理流程:

          f0443845a94a5e3a6514a7eb277968e7.webp

          這一點(diǎn)有點(diǎn)像webpack,webpack本身僅做依賴分析、抽象語法樹分析,其他的操作是靠插件和加載器完成的。

          • 官網(wǎng)地址:https://postcss.org/
          • github地址:https://github.com/postcss/postcss

          安裝

          PostCss是基于node編寫的,因此可以使用npm安裝

          npm?i?-D?postcss

          postcss庫(kù)提供了對(duì)應(yīng)的js api用于轉(zhuǎn)換代碼,如果你想使用postcss的一些高級(jí)功能,或者想開發(fā)postcss插件,就要api使用postcss,api的文檔地址是:http://api.postcss.org/

          不過絕大部分時(shí)候,我們都是使用者,并不希望使用代碼的方式來使用PostCss

          因此,我們可以再安裝一個(gè)postcss-cli,通過命令行來完成編譯

          npm?i?-D?postcss-cli

          postcss-cli提供一個(gè)命令,它調(diào)用postcss中的api來完成編譯

          命令的使用方式為:

          postcss?源碼文件?-o?輸出文件

          配置文件

          和webpack類似,postcss有自己的配置文件,該配置文件會(huì)影響postcss的某些編譯行為。

          配置文件的默認(rèn)名稱是:postcss.config.js

          例如:

          module.exports?=?{
          ????map:?false,?//關(guān)閉source-map
          }

          插件

          光使用postcss是沒有多少意義的,要讓它真正的發(fā)揮作用,需要插件

          postcss的插件市場(chǎng):https://www.postcss.parts/

          下面羅列一些postcss的常用插件:

          1. postcss-preset-env

          過去使用postcss的時(shí)候,往往會(huì)使用大量的插件,它們各自解決一些問題,這樣導(dǎo)致的結(jié)果是安裝插件、配置插件都特別的繁瑣。

          于是出現(xiàn)了這么一個(gè)插件postcss-preset-env,它稱之為postcss預(yù)設(shè)環(huán)境,大意就是它整合了很多的常用插件到一起,并幫你完成了基本的配置,你只需要安裝它一個(gè)插件,就相當(dāng)于安裝了很多插件了。

          安裝好該插件后,在postcss配置中加入下面的配置

          module.exports?=?{
          ????plugins:?{
          ????????"postcss-preset-env":?{}?//?{}?中可以填寫插件的配置
          ????}
          }

          這個(gè)插件里面有很多功能,比如說:

          • 自動(dòng)廠商前綴

          可以實(shí)現(xiàn)某些新的css樣式需要在舊版本瀏覽器中使用廠商前綴

          例如:

          ::placeholder?{
          ????color:?red;
          }

          這個(gè)功能在不同的舊版本瀏覽器中需要書寫為

          ::-moz-placeholder{
          ????color:?red;
          ???
          }
          :-ms-input-placeholder{
          ????color:?red;
          ???
          }
          ::placeholder{
          ????color:?red;
          ???
          }

          要完成這件事情,需要使用autoprefixer庫(kù)。而postcss-preset-env內(nèi)部包含了該庫(kù),自動(dòng)有了該功能。

          如果需要調(diào)整兼容的瀏覽器范圍,可以通過下面的方式進(jìn)行配置:

          【方式1】:添加 .browserslistrc文件

          創(chuàng)建文件.browserslistrc,填寫配置內(nèi)容

          last?2?version
          >?1%

          【方式2】:在package.json的配置中加入browserslist

          "browserslist":?[
          ????"last?2?version",
          ????">?1%"
          ]

          browserslist是一個(gè)多行的(數(shù)組形式的)標(biāo)準(zhǔn)字符串。

          它的書寫規(guī)范多而繁瑣,詳情見:https://github.com/browserslist/browserslist

          一般情況下,大部分網(wǎng)站都使用下面的格式進(jìn)行書寫

          last?2?version
          >?1%?in?CN
          not?ie?<=?8
          • last 2 version: 瀏覽器的兼容最近期的兩個(gè)版本
          • 1% in CN: 匹配中國(guó)大于1%的人使用的瀏覽器, in CN可省略
          • not ie <= 8: 排除掉版本號(hào)小于等于8的IE瀏覽器 ?默認(rèn)情況下,匹配的結(jié)果求的是并集。

          可以通過網(wǎng)站:https://browserl.ist/ ??對(duì)配置結(jié)果覆蓋的瀏覽器進(jìn)行查詢,查詢時(shí),多行之間使用英文逗號(hào)分割。

          ?browserlist的數(shù)據(jù)來自于CanIUse網(wǎng)站,由于數(shù)據(jù)不是實(shí)時(shí)的,所以不會(huì)特別準(zhǔn)確

          • 未來的CSS語法

          CSS的某些前沿語法正在制定過程中,沒有形成真正的標(biāo)準(zhǔn),如果希望使用這部分語法,為了瀏覽器兼容性,需要進(jìn)行編譯

          過去,完成該語法編譯的是cssnext庫(kù),不過有了postcss-preset-env后,它自動(dòng)包含了該功能。

          我們可以通過postcss-preset-env的stage配置,告知postcss-preset-env需要對(duì)哪個(gè)階段的css語法進(jìn)行兼容處理,它的默認(rèn)值為2

          "postcss-preset-env":?{
          ????stage:?0
          }

          一共有5個(gè)階段可配置:

          1. Stage 0: Aspirational - 只是一個(gè)早期草案,極其不穩(wěn)定
          2. Stage 1: Experimental - 仍然極其不穩(wěn)定,但是提議已被W3C公認(rèn)
          3. Stage 2: Allowable - 雖然還是不穩(wěn)定,但已經(jīng)可以使用了
          4. Stage 3: Embraced - 比較穩(wěn)定,可能將來會(huì)發(fā)生一些小的變化,它即將成為最終的標(biāo)準(zhǔn)
          5. Stage 4: Standardized - 所有主流瀏覽器都應(yīng)該支持的W3C標(biāo)準(zhǔn) 了解了以上知識(shí)后,接下來了解一下未來的css語法,盡管某些語法仍處于非常早期的階段,但是有該插件存在,編譯后仍然可以被瀏覽器識(shí)別

          ① 變量

          未來的css語法是天然支持變量的

          :root{}中定義常用變量,使用--前綴命名變量

          :root{
          ????--lightColor:?#ddd;
          ????--darkColor:?#333;
          }

          a{
          ????color:?var(--lightColor);
          ????background:?var(--darkColor);
          }

          編譯后,仍然可以看到原語法,因?yàn)槟承┬抡Z法的存在并不會(huì)影響瀏覽器的渲染,盡管瀏覽器可能不認(rèn)識(shí) 如果不希望在結(jié)果中看到新語法,可以配置postcss-preset-envpreservefalse

          ② 自定義選擇器

          @custom-selector?:--heading?h1,?h2,?h3,?h4,?h5,?h6;
          @custom-selector?:--enter?:focus,:hover;

          a:--enter{
          ????color:?#f40;
          }

          :--heading{
          ????font-weight:bold;
          }

          :--heading.active{
          ????font-weight:bold;
          }

          編譯后

          a:focus,a:hover{
          ????color:?#f40;
          }

          h1,h2,h3,h4,h5,h6{
          ????font-weight:bold;
          }

          h1.active,h2.active,h3.active,h4.active,h5.active,h6.active{
          ????font-weight:bold;
          }

          ③ 嵌套

          與LESS相同,只不過嵌套的選擇器前必須使用符號(hào)&

          .a?{
          ????color:?red;
          ????&?.b?{
          ????????color:?green;
          ????}

          ????&?>?.b?{
          ????????color:?blue;
          ????}

          ????&:hover?{
          ????????color:?#000;
          ????}
          }

          編譯后

          .a?{
          ????color:?red
          }

          .a?.b?{
          ????color:?green;
          }

          .a>.b?{
          ????color:?blue;
          }

          .a:hover?{
          ????color:?#000;
          }

          2、postcss-apply

          這個(gè)插件可以支持在css中書寫屬性集,類似于LESS中的混入,可以利用CSS的新語法定義一個(gè)CSS代碼片段,然后在需要的時(shí)候應(yīng)用它。

          :root?{
          ??--center:?{
          ????position:?absolute;
          ????left:?50%;
          ????top:?50%;
          ????transform:?translate(-50%,?-50%);
          ??};
          }

          .item{
          ????@apply?--center;
          }

          編譯后

          .item{
          ??position:?absolute;
          ??left:?50%;
          ??top:?50%;
          ??-webkit-transform:?translate(-50%,?-50%);
          ??transform:?translate(-50%,?-50%);
          }

          ?實(shí)際上,該功能也屬于cssnext,不知為何postcss-preset-env沒有支持

          3、 postcss-color-function

          該插件支持在源碼中使用一些顏色函數(shù)

          body?{
          ????/*?使用顏色#aabbcc,不做任何處理,等同于直接書寫?#aabbcc?*/
          ????color:?color(#aabbcc);
          ????/*?將顏色#aabbcc透明度設(shè)置為90%?*/
          ????color:?color(#aabbcc?a(90%));
          ????/*?將顏色#aabbcc的紅色部分設(shè)置為90%?*/
          ????color:?color(#aabbcc?red(90%));
          ????/*?將顏色#aabbcc調(diào)亮50%(更加趨近于白色),類似于less中的lighten函數(shù)?*/
          ????color:?color(#aabbcc?tint(50%));
          ????/*?將顏色#aabbcc調(diào)暗50%(更加趨近于黑色),類似于less中的darken函數(shù)?*/
          ????color:?color(#aabbcc?shade(50%));
          }

          編譯后

          body?{
          ????/*?使用顏色#aabbcc,不做任何處理,等同于直接書寫?#aabbcc?*/
          ????color:?rgb(170,?187,?204);
          ????/*?將顏色#aabbcc透明度設(shè)置為90%?*/
          ????color:?rgba(170,?187,?204,?0.9);
          ????/*?將顏色#aabbcc的紅色部分設(shè)置為90%?*/
          ????color:?rgb(230,?187,?204);
          ????/*?將顏色#aabbcc調(diào)亮50%(更加趨近于白色),類似于less中的lighten函數(shù)?*/
          ????color:?rgb(213,?221,?230);
          ????/*?將顏色#aabbcc調(diào)暗50%(更加趨近于黑色),類似于less中的darken函數(shù)?*/
          ????color:?rgb(85,?94,?102);
          }

          4、stylelint

          官網(wǎng):https://stylelint.io/

          在實(shí)際的開發(fā)中,我們可能會(huì)錯(cuò)誤的或不規(guī)范的書寫一些css代碼,stylelint插件會(huì)實(shí)時(shí)的發(fā)現(xiàn)錯(cuò)誤。

          由于不同的公司可能使用不同的CSS書寫規(guī)范,stylelint為了保持靈活,它本身并沒有提供具體的規(guī)則驗(yàn)證。

          你需要安裝或自行編寫規(guī)則驗(yàn)證方案

          通常,我們會(huì)安裝tylelint-config-standard庫(kù)提供標(biāo)準(zhǔn)的CSS規(guī)則判定

          安裝好后,我們需要告訴stylelint使用該庫(kù)來進(jìn)行規(guī)則驗(yàn)證,告訴的方式有多種,比較常見的是使用文件.stylelintrc

          //.styleintrc
          {
          ??"extends":?"stylelint-config-standard"
          }

          此時(shí),如果你的代碼出現(xiàn)不規(guī)范的地方,編譯時(shí)將會(huì)報(bào)出錯(cuò)誤

          body?{
          ????background:?#f4;
          }

          發(fā)生了兩處錯(cuò)誤:

          1b344c9e0c8db6fbc54391eb992dca3c.webp
          • 縮進(jìn)應(yīng)該只有兩個(gè)空格
          • 十六進(jìn)制的顏色值不正確

          如果某些規(guī)則不是我們所期望的,可以在配置中進(jìn)行設(shè)置:

          {
          ????"extends":?"stylelint-config-standard",
          ????"rules":?{
          ????????"indentation":?null
          ????}
          }

          設(shè)置為null可以禁用該規(guī)則,或者設(shè)置為4,表示一個(gè)縮進(jìn)有4個(gè)空格。具體的設(shè)置需要參見stylelint文檔:https://stylelint.io/

          但是這種錯(cuò)誤報(bào)告需要在編譯時(shí)才會(huì)發(fā)生,如果我希望在編寫代碼時(shí)就自動(dòng)在編輯器里報(bào)錯(cuò)呢?如果想在編輯器里達(dá)到該功能,安裝vscode的插件stylelint就可以了,它會(huì)讀取你工程中的配置文件,按照配置進(jìn)行實(shí)時(shí)報(bào)錯(cuò)。

          解決css文件細(xì)分問題

          這一部分,就要依靠構(gòu)建工具,例如webpack來解決了,利用一些loader或plugin來打包、合并、壓縮css文件。

          「利用webpack拆分css」

          要拆分css,就必須把css當(dāng)成像js那樣的模塊;要把css當(dāng)成模塊,就必須有一個(gè)構(gòu)建工具(webpack),它具備合并代碼的能力,而webpack本身只能讀取css文件的內(nèi)容、將其當(dāng)作JS代碼進(jìn)行分析,因此,會(huì)導(dǎo)致錯(cuò)誤。

          于是,就必須有一個(gè)loader,能夠?qū)ss代碼轉(zhuǎn)換為js代碼

          「css-loader」

          css-loader的作用,就是將css代碼轉(zhuǎn)換為js代碼,它的處理原理簡(jiǎn)單到令人發(fā)指:就是將css代碼作為字符串導(dǎo)出。

          例如:

          .red{
          ????color:"#f40";
          }

          經(jīng)過css-loader轉(zhuǎn)換后變成js代碼:

          module.exports?=?`.red{
          ????color:"#f40";
          }`

          上面的js代碼是經(jīng)過我簡(jiǎn)化后的,不代表真實(shí)的css-loader的轉(zhuǎn)換后代碼,css-loader轉(zhuǎn)換后的代碼會(huì)有些復(fù)雜,同時(shí)會(huì)導(dǎo)出更多的信息,但核心思想不變。

          再例如:

          .red{
          ????color:"#f40";
          ????background:url("./bg.png")
          }

          經(jīng)過css-loader轉(zhuǎn)換后變成js代碼:

          var?import1?=?require("./bg.png");
          module.exports?=?`.red{
          ????color:"#f40";
          ????background:url("${import1}")
          }`
          ;

          這樣一來,經(jīng)過webpack的后續(xù)處理,會(huì)把依賴./bg.png添加到模塊列表,然后再將代碼轉(zhuǎn)換為

          var?import1?=?__webpack_require__("./src/bg.png");
          module.exports?=?`.red{
          ????color:"#f40";
          ????background:url("${import1}")
          }`
          ;

          再例如:

          @import?"./reset.css";
          .red{
          ????color:"#f40";
          ????background:url("./bg.png")
          }

          會(huì)轉(zhuǎn)換為:

          var?import1?=?require("./reset.css");
          var?import2?=?require("./bg.png");
          module.exports?=?`${import1}
          .red{
          ????color:"#f40";
          ????background:url("${import2}")
          }`
          ;

          總結(jié),css-loader干了什么:

          1. 將css文件的內(nèi)容作為字符串導(dǎo)出
          2. 將css中的其他依賴作為require導(dǎo)入,以便webpack分析依賴

          「style-loader」

          由于css-loader僅提供了將css轉(zhuǎn)換為字符串導(dǎo)出的能力,剩余的事情要交給其他loader或plugin來處理。

          style-loader可以將css-loader轉(zhuǎn)換后的代碼進(jìn)一步處理,將css-loader導(dǎo)出的字符串加入到頁(yè)面的style元素中

          例如:

          .red{
          ????color:"#f40";
          }

          經(jīng)過css-loader轉(zhuǎn)換后變成js代碼:

          module.exports?=?`.red{
          ????color:"#f40";
          }`

          經(jīng)過style-loader轉(zhuǎn)換后變成:

          module.exports?=?`.red{
          ????color:"#f40";
          }`


          var?style?=?module.exports;
          var?styleElem?=?document.createElement("style");
          styleElem.innerHTML?=?style;
          document.head.appendChild(styleElem);
          module.exports?=?{}

          以上代碼均為簡(jiǎn)化后的代碼,并不代表真實(shí)的代碼,style-loader是有能力避免同一個(gè)樣式的重復(fù)導(dǎo)入

          「抽離css文件」

          目前,css代碼被css-loader轉(zhuǎn)換后,交給的是style-loader進(jìn)行處理。style-loader使用的方式是用一段js代碼,將樣式加入到style元素中。而實(shí)際的開發(fā)中,我們往往希望依賴的樣式最終形成一個(gè)css文件,此時(shí),就需要用到一個(gè)庫(kù):mini-css-extract-plugin

          該庫(kù)提供了1個(gè)plugin和1個(gè)loader

          • plugin:負(fù)責(zé)生成css文件
          • loader:負(fù)責(zé)記錄要生成的css文件的內(nèi)容,同時(shí)導(dǎo)出開啟css-module后的樣式對(duì)象

          使用方式:

          const?MiniCssExtractPlugin?=?require("mini-css-extract-plugin")
          module.exports?=?{
          ????module:?{
          ????????rules:?[
          ????????????{
          ????????????????test:?/\.css$/,?use:?[MiniCssExtractPlugin.loader,?"css-loader?modules"]
          ????????????}
          ????????]
          ????},
          ????plugins:?[
          ????????new?MiniCssExtractPlugin()?//負(fù)責(zé)生成css文件
          ????]
          }

          配置生成的文件名

          output.filename的含義一樣,即根據(jù)chunk生成的樣式文件名。

          配置生成的文件名,例如[name].[contenthash:5].css

          默認(rèn)情況下,每個(gè)chunk對(duì)應(yīng)一個(gè)css文件。

          ?? 最后

          若本文對(duì)于 CSS工程化 閱讀有任何錯(cuò)誤的地方,歡迎大家給我提意見,一定虛心聽取你們的指正,若覺得不錯(cuò)的,也可以點(diǎn)個(gè)??「star」 ?? 支持一下我。

          最后,也可以關(guān)注我的公眾號(hào):「人生不只有技術(shù)」,或是添加我的微信(wKavin)私底下進(jìn)行交流 這篇文章我真的很用心了,你們?nèi)绦牟唤o點(diǎn)個(gè)贊 ?? 和 在看 嘛~

          「歡迎各位大佬關(guān)注我,掃二維碼即可」

          瀏覽 41
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日日夜夜影音先锋 | 精品国产欧美一区二区三区成人 | 高清国产mv在线观看 | 欧美性猛交一区二区三区精品 | 国产熟女操逼 |