1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        CSS工程化

        共 12226字,需瀏覽 25分鐘

         ·

        2021-03-01 23:48

        ????

        db79b846b42c8ee08d843c8ecce92238.webp


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

        css的問題

        類名沖突的問題

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

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

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

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

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

        重復(fù)樣式

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

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

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

        css文件細(xì)分問題

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

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

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

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

        如何解決

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

        解決類名沖突

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

        「命名約定」

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

        • BEM
        • OOCSS
        • AMCSS
        • SMACSS
        • 其他

        我主要以BEM為例說下:

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

        BEM全稱是:Block Element Modifier

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

        80d7fc2669331ecd943d4f2cb8453b76.webp

        三個部分的具體含義為:

        • Block :頁面中的大區(qū)域,表示最頂級的劃分,例如:輪播圖(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)的輪播圖小圓點(banner__dot_selected) 在某些大型工程中,如果使用BEM命名法,還可能會增加一個前綴,來表示類名的用途,常見的前綴有:

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

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

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

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

        「css in js」

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

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

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

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

        例如下面的對象就是一個用于描述樣式的對象:

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

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

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

        css in js 的特點

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

        「css module」

        非常有趣和好用的css模塊化方案,編寫簡單,絕對不重名

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

        思路:

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

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

        實現(xiàn)原理

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

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

        d8fc740e8ee2dbf7735eb3a865de40bc.webp

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

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

        2155ecdd03b2d87c87bef7673513eca7.webp

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

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

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

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

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

        其他操作

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

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

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

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

        • 如何控制最終的類名 絕大部分情況下,我們都不需要控制最終的類名,因為控制它沒有任何意義

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

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

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

        「css in js」

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

        「css預(yù)編譯器」

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

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

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

        • less
        • sass

        基本原理

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

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

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

        032377b94662e666d0f65a9e5166f7a7.webp目前,最流行的預(yù)編譯器有LESS和SASS,它們兩個特別相似,這里主要說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之后,它提供了一個CLI工具lessc,通過該工具即可完成編譯

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

        光說不練假把式:

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

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

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

        運行命令:

        lessc?index.less?index.css

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

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

        LESS的基本使用

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

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

        「postcss」

        什么是PostCss?

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

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

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

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

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

        f3931b8afa401c09f47c82f4f75dbe09.webp

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

        f0443845a94a5e3a6514a7eb277968e7.webp

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

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

        安裝

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

        npm?i?-D?postcss

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

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

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

        npm?i?-D?postcss-cli

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

        命令的使用方式為:

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

        配置文件

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

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

        例如:

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

        插件

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

        postcss的插件市場:https://www.postcss.parts/

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

        1. postcss-preset-env

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

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

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

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

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

        • 自動廠商前綴

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

        例如:

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

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

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

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

        如果需要調(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是一個多行的(數(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: 瀏覽器的兼容最近期的兩個版本
        • 1% in CN: 匹配中國大于1%的人使用的瀏覽器, in CN可省略
        • not ie <= 8: 排除掉版本號小于等于8的IE瀏覽器 ?默認(rèn)情況下,匹配的結(jié)果求的是并集。

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

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

        • 未來的CSS語法

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

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

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

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

        一共有5個階段可配置:

        1. Stage 0: Aspirational - 只是一個早期草案,極其不穩(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)定,可能將來會發(fā)生一些小的變化,它即將成為最終的標(biāo)準(zhǔn)
        5. Stage 4: Standardized - 所有主流瀏覽器都應(yīng)該支持的W3C標(biāo)準(zhǔn) 了解了以上知識后,接下來了解一下未來的css語法,盡管某些語法仍處于非常早期的階段,但是有該插件存在,編譯后仍然可以被瀏覽器識別

        ① 變量

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

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

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

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

        編譯后,仍然可以看到原語法,因為某些新語法的存在并不會影響瀏覽器的渲染,盡管瀏覽器可能不認(rèn)識 如果不希望在結(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相同,只不過嵌套的選擇器前必須使用符號&

        .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

        這個插件可以支持在css中書寫屬性集,類似于LESS中的混入,可以利用CSS的新語法定義一個CSS代碼片段,然后在需要的時候應(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%);
        }

        ?實際上,該功能也屬于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/

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

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

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

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

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

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

        此時,如果你的代碼出現(xiàn)不規(guī)范的地方,編譯時將會報出錯誤

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

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

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

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

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

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

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

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

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

        「利用webpack拆分css」

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

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

        「css-loader」

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

        例如:

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

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

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

        上面的js代碼是經(jīng)過我簡化后的,不代表真實的css-loader的轉(zhuǎn)換后代碼,css-loader轉(zhuǎn)換后的代碼會有些復(fù)雜,同時會導(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ù)處理,會把依賴./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")
        }

        會轉(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)出的字符串加入到頁面的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?=?{}

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

        「抽離css文件」

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

        該庫提供了1個plugin和1個loader

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

        使用方式:

        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)情況下,每個chunk對應(yīng)一個css文件。

        ?? 最后

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

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

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

        瀏覽 41
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产精品天天爽视频 | 张开腿插入 | 91成人电影在线 | 国产麻豆成人免费视频 | 美女自慰网址 | 从后面挺进丝袜老师的身体 | 国产精品18久久久久白浆 | 人妻无码精品久久人妻成人 | 国产尤物视频在线观看 | 国产成人精品综合在线观看 |