瘦身50%-70%,攜程 Taro 小程序樣式 Size 縮減方案
本文樣式方案學(xué)習(xí)了 cssModules 解決樣式?jīng)_突的基本原理,并在此基礎(chǔ)上改進(jìn)以達(dá)到縮減樣式文件 Size 的目的。
作者簡(jiǎn)介
(資料圖)
Can,攜程前端開發(fā),目前從事小程序開發(fā)工作,對(duì)編譯打包技術(shù)、小程序跨平臺(tái)解決方案有濃厚興趣。
一、概述
目前我們團(tuán)隊(duì)小程序是使用 Taro 跨端方案 React 框架進(jìn)行開發(fā),基于現(xiàn)有樣式方案,在編譯打包后會(huì)產(chǎn)生大量的樣式代碼冗余,在項(xiàng)目編譯后的產(chǎn)物中占有較大比例。
分析了編譯后的樣式代碼后,我們發(fā)現(xiàn)冗余代碼主要體現(xiàn)在兩個(gè)方面:
項(xiàng)目樣式文件中大量使用了父子選擇器作為作用域進(jìn)行樣式隔離,編譯后出現(xiàn)類名大量重復(fù)冗余。如以下 SCSS 文件樣式代碼中,編譯后.box .item重復(fù)冗余了三次。// 編譯前代碼.box { .item { .item1 {} .item2 {} .item3 {} .item4 {} }}// 編譯后代碼.box .item .item1 {}.box .item .item2 {}.box .item .item3 {}.box .item .item4 {}
樣式代碼中大量屬性值重復(fù)冗余。如最常用的display: flex屬性值,在項(xiàng)目中可能存在幾百上千份重復(fù)冗余,而且為了兼容性開啟了 Autoprefixer 插件后,display:flex將會(huì)變成display:-webkit-flex;display:-ms-flexbox;display:flex;,使得樣式文件屬性值的冗余情況更為嚴(yán)重。針對(duì) Taro項(xiàng)目 React 框架小程序遇到的以上問題,本文將介紹一種新的樣式解決方案。本方案在較少改變現(xiàn)有開發(fā)體驗(yàn)的條件下,采用 cssModules 樣式方案語法要求,利用 Taro 插件的便利性給出對(duì)應(yīng)的解決方案,以此對(duì)產(chǎn)物進(jìn)行“瘦身”。最終樣式文件的瘦身效果可以達(dá)到 50% – 70%,進(jìn)一步緩解官方包 Size 的限制,便于業(yè)務(wù)的高速發(fā)展。
二、cssModules 簡(jiǎn)單介紹
本文樣式方案學(xué)習(xí)了 cssModules 解決樣式?jīng)_突的基本原理,并在此基礎(chǔ)上改進(jìn)以達(dá)到縮減樣式文件 Size 的目的。因此在正式了解本方案之前,本文先用 Taro 官網(wǎng)中使用 cssModules 方案的例子代碼作為示例,簡(jiǎn)單了解下其語法要求與原理。
2.1 語法要求
在配置開啟了 cssModules 后,按照語法要求,Taro 項(xiàng)目中有 index.module.scss 和 index.js 兩個(gè)文件,文件代碼如下。cssModules 默認(rèn)是開啟部分自定義模式轉(zhuǎn)換,只有文件名中包含.module.的樣式文件才會(huì)經(jīng)過 cssModules 轉(zhuǎn)換處理。在如下 index.module.scss 樣式文件中,我們正常使用了父子選擇器、類選擇器。但是在index.js 文件中,className 賦值不再是字符串,而是 SCSS 文件導(dǎo)出的 Object 的某個(gè) Key,該 Key 為 SCSS 文件中的類選擇器的命名。
import React, { Component } from "react"import { View, Text } from "@tarojs/components"import styles from "./index.module.scss"export default class Index extends Component { render() { return ( Hello world! ) }}
.test { color: red; .txt { font-size: 36px; }}
2.2 原理
Taro 項(xiàng)目開啟 cssModules 配置后,在編譯打包時(shí),會(huì)使用實(shí)現(xiàn)了 cssModules 規(guī)范的 css-loader 對(duì) SCSS 等樣式文件進(jìn)行處理。它首先會(huì)處理原 SCSS 文件中的類選擇器,將類名進(jìn)行哈希處理得到新類名如index-module__test___Bm2J6,生成新的樣式代碼輸出到最終的 index.wxss,同時(shí)保存了原類名與哈希處理后的新類名的映射關(guān)系。此后它會(huì)將原 SCSS 文件 index.module.scss 編譯為導(dǎo)出了原類名與哈希后的新類名的映射對(duì)象。JS 文件在運(yùn)行時(shí)能通過該映射對(duì)象獲取到哈希后的新類名,保證該文件類名不會(huì)與其他樣式文件的同類名沖突,從而解決樣式?jīng)_突問題。以下為編譯后的代碼示例,styles.test在運(yùn)行時(shí)會(huì)會(huì)變成index-module__test___Bm2J6。
// index.module.scssexport default ({"test":"index-module__test___Bm2J6","txt":"index-module__txt___nIysk"});
// index.wxss.index-module__test___Bm2J6 { color: red;}.index-module__test___Bm2J6 .index-module__txt___nIysk { font-size: 36rpx;}
三、方案原理介紹
3.1 基本原理
3.1.1 當(dāng)前樣式文件 size 分析
在正式介紹本文方案是如何縮減樣式文件 Size 之前,本文通過以下兩個(gè)正則去分別匹配打包產(chǎn)物中所有樣式文件的兩個(gè)核心組成部分 ClassName 與 PropertyValue,并進(jìn)行 Size 統(tǒng)計(jì)分析。
注:在本文中,有如該.txt .tit {color: #red;}CssRule代碼,ClassName指的是其中的txt和tit,PropertyValue指的是color:#red;。
const classNamePattern = /(?<=\.)[A-Za-z0-9\-_]+(?=\s|{|:)/g // 匹配 ClassName 如 .txt {color: #red;}中的txtconst cssPropertyPattern = /(?<=\{)[^}]+(?=})/g // 匹配PropertyValue, 如 .txt {color: #red;}中 中括號(hào)之間的所有內(nèi)容 color: #red;
下圖是對(duì)整個(gè)編譯打包后的小程序項(xiàng)目的樣式文件進(jìn)行組成 Size 分析。通過該圖我們可以發(fā)現(xiàn),我們項(xiàng)目打包編譯后的所有的樣式文件中,ClassName 占用大約有五分之一的空間,而 PropertyValue 則占用了有十分之七的空間,其余空間占比可能是如空格、偽類這種形態(tài)存在,本文暫不考慮。
3.1.2 處理方案
通過上一小節(jié),我們可以知道一個(gè)樣式文件中核心主要有兩部分內(nèi)容,一是 ClassName,二是 PropertyValue。本文樣式方案對(duì)這兩部分分別進(jìn)行了處理來達(dá)到節(jié)省 Size 的目標(biāo)。
1)縮減 ClassName 長(zhǎng)度
核心就是將原 ClassName 替換成更短且唯一的 ClassName,在解決樣式?jīng)_突的同時(shí),也通過縮減了 ClassName 長(zhǎng)度節(jié)省了 Size。當(dāng)我們使用 cssModules 時(shí),通常如第二章介紹 cssModules 時(shí)的示例代碼一樣,都是將 ClassName 進(jìn)行 hash 化處理來保證唯一性,但是經(jīng)過 hash 處理后的 ClassName 長(zhǎng)度反而變得更長(zhǎng)了,不符合我們縮減樣式代碼 Size 的目標(biāo)。
本方案是從最短字符開始,逐漸遞增的方式生成全項(xiàng)目唯一的 ClassName,從而保證唯一性的同時(shí)能夠保證 ClassName 長(zhǎng)度盡可能的短。如第一個(gè)解析到的 ClassName 替換成-a,第二個(gè)解析到的ClassName替換成-b,第五十二個(gè)解析到的 ClassName 替換成-Z,第五十三個(gè)解析到的 ClassName 替換成-aa。其中 ClassName 前面的-,用于防止新生成的類名與未轉(zhuǎn)換的類名沖突。此外,新生成的 ClassName 注意需要符合規(guī)則,本插件算法先取prevString中一個(gè)字符,后續(xù)所有字符可以取任意charString中字符。
const prevString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" // 52個(gè)字符數(shù)const charString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" // 64個(gè)字符數(shù)
可能有人擔(dān)心,隨著整個(gè)項(xiàng)目中 ClassName 申明的越來越多,逐漸遞增生成的 ClassName 也會(huì)越來越長(zhǎng),反而導(dǎo)致總 ClassName 過長(zhǎng)。通過上述算法,算上最前面加上的 -, 當(dāng)使用完三個(gè)字符長(zhǎng)度的類名可 以替換 52 * 64 = 3328 個(gè) ClassName 了,達(dá)到使用完四個(gè)字符長(zhǎng)度需要 52 * 64 * 64 = 212992 個(gè) className。新生成的 ClassName 不超過四個(gè)字符,就可以滿足大部分項(xiàng)目的使用,使用本樣式方案前可以檢索下自己項(xiàng)目中 ClassName 的量級(jí)。
2)縮減 PropertyValue
通過上面的分析可以發(fā)現(xiàn),其實(shí)占據(jù)樣式文件 Size 最多的部分是 PropertyValue,因此縮減 PropertyValue 是本樣式方案能夠節(jié)省大量 Size 的核心手段。其實(shí)我們?cè)陂_發(fā)時(shí)用到的樣式屬性值很多都是重復(fù)的,比如開發(fā)過程中用到的最多布局屬性display:flex。每次用到該屬性都需要新寫一份,而且為了兼容性開啟了Autoprefixer插件,display:flex將會(huì)變成display:-webkit-flex;display:-ms-flexbox;display:flex;,這使得樣式文件的 Size 變得更大。本插件是通過盡可能復(fù)用 PropertyValue 的方式來縮減 PropertyValue。
本插件會(huì)將樣式文件中的僅使用了類選擇器的 CssRule 進(jìn)行 PropertyValue 拆分,每一次拆分都會(huì)生成新的 PropertyValue ClassName。如以下示例代碼,僅類選擇器CssRuletxt被拆分了_a和_b兩個(gè) PropertyValue ClassName。后續(xù)若其他使用僅類選擇器 CssRule 進(jìn)行拆分時(shí),若有相同的 PropertyValue 就會(huì)直接復(fù)用_a或者_(dá)b。
// 原代碼.txt { display: flex;flex: 1; }// 處理后的代碼._a {display: -webkit-flex; display: -ms-flexbox;display: flex;}._b {-webkit-flex: 1;-ms-flex: 1;flex: 1;}
而在使用 cssModules 樣式寫法的 js 文件中也需要進(jìn)行相應(yīng)的映射處理,通過 babel 插件在編譯時(shí)進(jìn)行轉(zhuǎn)換處理,判斷 css 文件的引用關(guān)系并進(jìn)行替換,示例代碼如下。
// 原代碼import styles from "./index.module.scss"Index = () => { return }// 處理后的代碼import "./index.module.scss"Index = () => { return }
本樣式方案通過對(duì)僅使用了類選擇器的 CssRule 的 PropertyValue 拆分成新的 PropertyValue ClassName,后續(xù)任何進(jìn)行拆分的地方就可以直接復(fù)用該 PropertyValue ClassName,從而可以大量縮減 PropertyValue 重復(fù)冗余占用的 Size。
3)插件處理流程
以上兩小節(jié)已經(jīng)介紹了兩個(gè)核心縮減 Size 的方案,本小節(jié)舉一個(gè)更加全面的例子來介紹本插件是如何在編譯時(shí)運(yùn)用以上兩個(gè)方案,對(duì)樣式文件和 JS 文件進(jìn)行處理轉(zhuǎn)化的。主要有以下兩步。
第一步,針對(duì)僅使用類選擇器的 CssRule,進(jìn)行 PropertyValue 拆分。如下示例代碼中,.box{display:flex}拆分出了._a {display: -webkit-flex;display: -ms-flexbox;display: flex;},后續(xù).item1` `.item2拆分時(shí),直接復(fù)用了._a,縮減了 PropertyValue 重復(fù)冗余。
第二步,針對(duì)非僅使用類選擇器的 CssRule,直接替換成全局唯一且更短的 ClassName。如下示例代碼中,.box .item2{color: red;},原選擇器中的 ClassName 直接替換成了更短的.-a .-b{ color: red;},并且添加了該映射關(guān)系styles = {box: “_a -a”, item1: “_a _b _c”, item2: “_a _b _d -b”},并在編譯時(shí)進(jìn)行替換。
// 原代碼import React from "react"import styles from "./index.module.scss"export default Index = () => { return item1 item2 }// 處理后的代碼import React from "react"import "./index.module.scss"http:// styles = {box: "_a -a", item1: "_a _b _c", item2: "_a _b _d -b"}export default Index = () => { return item1 item2 }
// 原index.module.scss代碼.box { display: flex;}.item1{ display: flex; font-size: 32px; color: red;}.item2{ display: flex; font-size: 32px; color: grey;}.box .item2{ color: red;}// 處理后index.module.scss代碼._a {display: -webkit-flex;display: -ms-flexbox;display: flex;}._b {font-size: 32px;}._c {color: red;}._d {color: grey;}.-a .-b{ color: red;}
3.2 需要注意的問題
3.2.1 styles 對(duì)象的屬性不支持運(yùn)行時(shí)
cssModules 方案中,JS 文件中引入的樣式文件對(duì)象支持運(yùn)行時(shí)計(jì)算屬性的,如以下示例寫法。這是因?yàn)樵诖虬蟮?JS 文件中,保存有一份原 ClassName 與 hash 后新 ClassName 映射關(guān)系的對(duì)象數(shù)據(jù),因此運(yùn)行時(shí) styles 還能映射屬性,但是這種處理方式會(huì)導(dǎo)致 js 文件 size 增大。
import styles from "./index.module.scss"const Index = () => { return }
本方案為了盡可能保證項(xiàng)目 Size 足夠小,并沒有采用 cssModules 這種處理方式。本方案在編譯時(shí)會(huì)直接對(duì)原 CLassName 與拆分 PropertyValue 后的新 ClassName 直接進(jìn)行了替換,如直接把className={styles.txt}替換成className=”_a _b”。
因此本方案styles對(duì)象不支持如上示例代碼中,運(yùn)行時(shí)計(jì)算得到txt屬性,如需動(dòng)態(tài)調(diào)整樣式有兩種方案,一是直接使用內(nèi)聯(lián)樣式。二是新寫 ClassName 而不是拼接,如className={value ? styles.txt1 : styles.txt2}}。
3.2.2 僅類選擇器不依賴先后順序定優(yōu)先級(jí)
在上文中,提到過會(huì)拆分僅使用類選擇器 CssRule,來盡可能復(fù)用已有的 PropertyValue ClassName。但是這種復(fù)用是有缺陷的,它會(huì)導(dǎo)致 ClassName 的先后順序可能不符合預(yù)期,如下代碼所示,通常來說我們認(rèn)為標(biāo)題顏色應(yīng)當(dāng)是grey。
// 原代碼import styles from "./index.module.scss"const Index = () => { return 標(biāo)題 }// 處理后的代碼import styles from "./index.module.scss"const Index = () => { return 標(biāo)題 }
// 原代碼.other { color: green; color:red; }.tit1 { color: red; }.tit2 { color: green; }// 處理后的代碼._a {color:green;}._b {color:red;}
但是經(jīng)過本插件復(fù)用了 PropertyValue 后,導(dǎo)致._b{color:red;}出現(xiàn)在了._a{color:green;}后面了,此時(shí)標(biāo)題的顏色也就變成了red,從而可能不符合開發(fā)者預(yù)期。
因此需要注意在編寫僅類選擇器 CssRule 的 ClassName 時(shí),不能依賴類選擇器先后順序來定優(yōu)先級(jí),可通過兄弟選擇器來將優(yōu)先級(jí)提的更高,從而不受先后順序影響,如下代碼示例。這樣就能確定標(biāo)題顏色一定是green。
// 兄弟選擇器來提高優(yōu)先級(jí).other { color: green; color:red; }.tit1 { color: red; }.tit1.tit2 { color: green; }
四、使用指南
4.1 使用
4.1.1 安裝插件
本樣式方案被集成在該 Taro 插件taro-plugin-split-class中,安裝本插件。源碼見倉庫taro-plugin-split-class。
npm install -D taro-plugin-split-class
4.1.2 關(guān)閉cssModules功能
在 Taro 配置文件中,使得mini.posetcss.cssModules.enable = false,確保 cssModules 功能關(guān)閉,如下代碼所示。
// config/index.js{ mini: { postcss: { cssModules: { enable: false } } }}
4.1.3 配置本插件
在 Taro 配置文件中,plugins配置中加入本插件taro-plugin-split-class。本插件支持配置類名轉(zhuǎn)換白名單(實(shí)現(xiàn)功能類似 : global,見 2.4)classNameWhite,比如常用的 iconfont 是不需要轉(zhuǎn)換的。
plugins: [ ["taro-plugin-split-class", { classNameWhite: ["iconfont", /^ifont-/] }]]
4.2 語法要求
a.樣式文件命名需以 .module.xxx 結(jié)尾,如 index.module.scss,該樣式文件方可被本插件轉(zhuǎn)化處理。
b. 在 JS 文件中,將樣式文件作為一個(gè)對(duì)象引入,并將類名作為對(duì)象的鍵進(jìn)行使用。如下代碼所示,使用className={styles.box}而不是className=”box”,其中box為定義在樣式文件的中類名。
// 如下import styles from "./index.module.scss" // 而不是import "./index.module.scss"
c. 本方案支持所有選擇器包括父子選擇器、偽類選擇器、兄弟選擇器等等。但請(qǐng)盡可能的使用僅類選擇器來定位元素,這樣做可以便于插件盡可能復(fù)用 PropertyValue 從而更好的縮減 Size。本方案解決了類名沖突問題,因此開發(fā)者不需要擔(dān)心因類名命名簡(jiǎn)單而導(dǎo)致的類名沖突。
// 如下僅類選擇器的CssRule.box { display: flex; flex-direction: column; align-items: center;}.tit { display: flex; font-size: 40px; color: red;}// 而不是父子選擇器.box { display: flex; flex-direction: column; align-items: center; .tit { display: flex; font-size: 40px; color: red; }}
d. 特殊類名不變
有時(shí)候我們希望一些特殊的 ClassName 不變,在 JS 文件中,不從 styles 取類名即可,如下代碼中的extra。
import styles from "./index.module.scss"標(biāo)題
但是在樣式文件中默認(rèn)所有 ClassName 都會(huì)被拆分或者壓縮。如下代碼示例,extra被處理成-a。
// 原類名.extra.tit {color: blue;}// 新類名.-a.-b { color: blue;}
因此需要特殊標(biāo)識(shí)符讓插件感知到不需要處理該 ClasName。本方案提供了類似 cssModules 的:global的解決方案,有兩種使用方式,一是:global(.extra),被包裹的類名不會(huì)被替換。
// 編譯前:global(.extra).tit { color: blue;}// 編譯后.extra.-a { color: blue;}
二是以:global開頭,后續(xù)所有的類名都不會(huì)被替換。
// 編譯前:global .extra1 .extra2 { color: red;}// 編譯后.extra1 .extra2 { color: red;}
4.3 打包效果展示
4.3.1 開發(fā)環(huán)境
使用本插件后,原類名會(huì)被替換或拆分成更短且更多的新類名。這樣處理后的新類名可讀性很差,開發(fā)者不能很好的定位到原類名代碼。因此在開發(fā)環(huán)境下,會(huì)在更短且更多的新類名前會(huì)加上[文件夾_文件名_原類名]。保留了原類名相關(guān)信息,便于開發(fā)者查找原類名。如下圖代碼所示,原類名為box,經(jīng)過插件拆分和縮短后的新類名為_a _g _h -c,在新類名前加上了index_indes-module_box,最終展示的完整類名為index_index-module_box _a _g _h -c。
4.3.2 生產(chǎn)環(huán)境
在生產(chǎn)環(huán)境了,不需要考慮新類名可讀性,因此直接會(huì)直接將類名完全替換為新類名。如下圖代碼所示,box直接被替換成_a _g _h -c。
五、方案分析
5.1 實(shí)踐效果
5.1.1 頁面改造前后對(duì)比
在使用本樣式方案對(duì)某個(gè)頁面進(jìn)行改造后,改造前后 Size 對(duì)比如下??梢园l(fā)現(xiàn)樣式文件縮減了 44KB,縮減了將近 70% 的 Size,JS 文件有這 2kb 的增長(zhǎng)。
JS文件 | 樣式文件 | 總和 | |
使用前 | 54kb | 63kb | 117kb |
使用后 | 56kb | 19kb | 75kb |
使用前編譯后文件 Size 如下圖:
使用后編譯后文件 Size 如下圖:
5.1.2 重構(gòu)頁面橫向?qū)Ρ?/strong>
最近我們項(xiàng)目重構(gòu)了兩個(gè)大型訂單詳情頁面,本小節(jié)以這兩個(gè)頁面重構(gòu)后的代碼為例,分析編譯打包前后的 Size 并進(jìn)行橫向?qū)Ρ取?/p>
整理出如下表格:
樣式編碼字符數(shù) | 打包后實(shí)際Size | |
未使用本樣式方案的訂單詳情頁1 | 3620 | 86kb |
使用本樣式方案的訂單詳情頁2 | 6615 | 73kb |
兩訂單詳情頁代碼組織結(jié)構(gòu)類似,因此將它們進(jìn)行橫向?qū)Ρ?。未采用本樣式方案的訂單詳情?1 的樣式編碼字符數(shù)為 3620,打包后實(shí)際 Size 為 86kb。若訂單詳情頁 2 未使用本樣式方案,打包前樣式編碼字符數(shù)為 6615,則預(yù)期打包后實(shí)際 Size 為 6615 / 3620 \* 86kb = 157kb,但訂單詳情頁使用了本樣式方案實(shí)際打包后為 73kb,相對(duì)于 157kb,縮減了 50% 左右的 Size。
以下為未使用本樣式方案的訂單詳情頁 1,該目錄下樣式文件包括了 50 個(gè)樣式文件,共計(jì) 3620 個(gè)字符,最終打包出來的樣式文件的 Size 為 86kb。
以下為使用了本樣式方案的訂單詳情頁 2,該目錄下樣式文件包括了 96 個(gè)樣式文件,共計(jì) 6615 個(gè)字符,最終打包出來的樣式文件 Size 為 73kb。
5.2 Size 縮減效果分析
以上兩個(gè)實(shí)踐效果,相較于項(xiàng)目中原樣式寫法方案,使用本方案后,主要從以下三個(gè)方面節(jié)省了 Size。
a. 本方案解決了樣式?jīng)_突問題,編寫樣式代碼時(shí)可以不再用父子選擇器的方式來進(jìn)行樣式作用域隔離,減少了祖先選擇器的冗余。如下使用了 sass 預(yù)處理器的樣式代碼所示,我們可以發(fā)現(xiàn)在最終編譯生成的代碼中,.box .item冗余了三次,而且若繼續(xù)在.box .item下每新增一個(gè)葉子節(jié)點(diǎn).item*,.box .item都會(huì)冗余一次。因此項(xiàng)目中使用父子選擇器這種方式來隔離作用域,會(huì)導(dǎo)致大量的祖先選擇器冗余。
// 編譯前代碼.box { .item { .item1 {} .item2 {} .item3 {} .item4 {} }}// 編譯后代碼.box .item .item1 {}.box .item .item2 {}.box .item .item3 {}.box .item .item4 {}
b. 將原 ClassName 直接縮短成更短的 ClassName,直接減少了字符數(shù)。這種方式較為直接,但優(yōu)化效果有限。
c. 本方案盡可能拆分樣式文件中僅類選擇器的 CssRule,生成并復(fù)用 PropertyValue ClassName,盡可能減少了 PropertyValue 的重復(fù)冗余。雖然在 JS 文件中 ClassName 被替換成更短但更多的 PropertyValue ClassName,有一定的 Size 增加,如在實(shí)踐效果 1 中,實(shí)踐后 JS 文件有 2KB 的增長(zhǎng)。但是相比于樣式文件 Size 上的縮減效果可以忽略不計(jì)。
5.3 Size 增長(zhǎng)分析
隨著樣式文件越多,采用本樣式方案的項(xiàng)目,樣式文件 Size 增長(zhǎng)幅度將增長(zhǎng)會(huì)越緩慢。本方案要求以僅類選擇器的方式為主,少量場(chǎng)景使用其他選擇器為輔的方式進(jìn)行編寫樣式代碼。隨著項(xiàng)目中樣式代碼越來越多,僅類選擇器 CssRule 經(jīng)過本插件處理拆分生成的可復(fù)用的 PropertyValue CssRule 會(huì)越來越多。此時(shí),在按要求新寫僅類選擇器 CssRule 使用到某個(gè) PropertyValue 時(shí),可復(fù)用的概率會(huì)更高。高概率的每一次復(fù)用都會(huì)節(jié)省一部分 Size,使得最終編譯打包后生成的樣式文件 Size 增長(zhǎng)曲率逐漸放緩。
六、總結(jié)
針對(duì) Taro 項(xiàng)目 React 框架小程序,本文介紹了一種新的樣式解決方案,該方案被集成為一個(gè) Taro 插件的形式,可以在在較少改變現(xiàn)有開發(fā)體驗(yàn)的條件下,緩解樣式代碼的冗余問題。
本樣式方案學(xué)習(xí)借鑒了 cssModules 樣式方案的語法規(guī)則以及原理,解決了樣式?jīng)_突的問題,并且在此基礎(chǔ)上從縮減 ClassName 長(zhǎng)度和縮減 PropertyValue 兩個(gè)方面實(shí)現(xiàn)了 Size 上的縮減,最終樣式文件的瘦身效果可以達(dá)到 50%-70%。這有利緩解官方包 Size 的限制,便于業(yè)務(wù)的高速發(fā)展。
七、vscode 插件推薦
本方案基本語法跟 cssModules 一致,因此可以直接借助現(xiàn)有的 cssModules 插件,提升開發(fā)體驗(yàn)。
7.1 CSS-Modules-transform 插件
該插件支持讓項(xiàng)目現(xiàn)有 JS 代碼快速轉(zhuǎn)成 cssModules 語法,將原類名使用方式,一鍵替換成本方案要求的類名使用語法,如classname=”a1″ => className={styles.a1}。需要注意的是,一鍵替換只支持非運(yùn)行時(shí)的語法,運(yùn)行時(shí)的語法還是需要手動(dòng)替換??梢愿咝岣攥F(xiàn)有樣式方案轉(zhuǎn)化效率。
7.2 CSS Modules 插件
CSS Modules插件支持自動(dòng)補(bǔ)全和類型定義,提高開發(fā)體驗(yàn)。
八、文章參考
GitHub – css-modules/css-modules: Documentation about css-modulescssModules插件圖片
-
科比布萊恩特再次成為《NBA
中國(guó)女足出征2023女足世界杯
購車優(yōu)惠3500元,特斯拉引薦
-
券商午后異動(dòng)急拉,個(gè)股悉數(shù)
女子稱自己患精神疾病兒子被
奇點(diǎn)汽車被申請(qǐng)破產(chǎn)審查 燒
上半年中歐班列累計(jì)開行8641列
2023年云南日?qǐng)?bào)報(bào)業(yè)集團(tuán)公開
廣州“三舊”改造實(shí)施辦法征
-
黑芝麻智能疑似深度綁定一汽
2023年蘭州城區(qū)普通高中錄取
跨界光伏者的N種“作死”法
路景交融 綠美常在 曲靖市
《八角籠中》成中國(guó)影史點(diǎn)映
唐山市疾控提醒:腸道傳染病
-
本人生日怎么發(fā)朋友圈圖片_
衛(wèi)生間應(yīng)放什么植物好
我的世界發(fā)射器怎樣發(fā)射(我
“低門檻”副業(yè)好做嗎?哪些
“后亞運(yùn)時(shí)代”頂級(jí)自辦賽事
熱熱熱!陽光的威力!廣東年
精彩推送
- 瘦身50%-70%,攜程 Taro 小程序樣式 Size 縮減方案
- 科比布萊恩特再次成為《NBA 2K24》封面球星
- 北京今年首批老舊小區(qū)改造名單公布,涉及這些小區(qū)
- 維信諾股東戶數(shù)下降6.36%,戶均持股30.5萬元
- 呂梁居然之家被罰款整改 存11項(xiàng)消防安全隱患
- 烏克蘭已正式申請(qǐng)加入CPTPP,日本:“必須仔細(xì)評(píng)估”
- 圣諾生物擬定增募資不超1.6億元 上市即巔峰募3.6億
- 致尚科技超募3.9億首日漲9.6% 過會(huì)曾被問3.26億買房
- 敏芯股份擬定增募不超1.5億 上市即巔峰募8.3億2022虧
- 首創(chuàng)證券收股轉(zhuǎn)系統(tǒng)監(jiān)管措施 持續(xù)督導(dǎo)未勤勉盡責(zé)
- 中國(guó)女足出征2023女足世界杯
- 高價(jià)防曬服是智商稅嗎?專家:未必效果更好
- 快資訊:煉油行業(yè)謀劃減碳發(fā)展路徑
- 津膜科技(300334)7月7日主力資金凈買入454.64萬元
- 新一代全球個(gè)護(hù)科技品牌TYMO完成數(shù)千萬人民幣A輪融資,康煦投資、零一創(chuàng)投出手
- 現(xiàn)金短款處理會(huì)計(jì)分錄
- 重慶三峽銀行五名董事辭職
- 出新必?zé)徜N!新世界耀勝尊府穩(wěn)據(jù)長(zhǎng)隆萬博CBD人氣封面
- 購車優(yōu)惠3500元,特斯拉引薦獎(jiǎng)勵(lì)升級(jí)
- 全球化3.0時(shí)代企業(yè)品牌出海新思維
- 魏晨陽對(duì)話王勇——數(shù)字經(jīng)濟(jì)時(shí)代的創(chuàng)新動(dòng)力
- 暑期游升溫 文化味更足——年中旅游市場(chǎng)觀察 天天消息
- 人均購買力平價(jià)gdp排名一覽 購買力平價(jià)計(jì)算公式是什么
- 公告!事關(guān)HPV疫苗預(yù)約接種
- 股票量化交易軟件:連續(xù)前行優(yōu)化第八部分程序改進(jìn)和修復(fù)
- 券商午后異動(dòng)急拉,個(gè)股悉數(shù)翻紅,券商ETF(512000)直線上攻漲逾1%!
- 購買力平價(jià)名詞解釋?購買力平價(jià)理論是誰提出來的?
- 教授稱有人花百萬留學(xué)回來月薪5000是真的嗎?國(guó)外留學(xué)回來工資多少?
- 銀行承兌匯票怎么承兌?為什么企業(yè)不愿意收承兌匯票?
- 私營(yíng)企業(yè)破產(chǎn)清算賠償五大順序是什么?破產(chǎn)清算對(duì)法人的影響大嗎?
- 公司破產(chǎn)清算要多久才完成?破產(chǎn)清算原有物資怎么處理?
- 銀行承兌幾個(gè)月到期?建行承兌貼現(xiàn)一般幾個(gè)點(diǎn)?
- 破產(chǎn)清算組由哪些人組成?破產(chǎn)清算和破產(chǎn)重組的區(qū)別是什么?
- 破產(chǎn)清算員工怎么賠償?公司申請(qǐng)破產(chǎn)的條件有哪些?
- 北京經(jīng)開區(qū)國(guó)家級(jí)專精特新企業(yè)達(dá)87家——“小巨人”扎堆凸顯科創(chuàng)實(shí)力 當(dāng)前熱點(diǎn)
- 傳奇手游藍(lán)月無限刀福利版:藍(lán)月傳奇寶石獲取攻略
- 河南新鄉(xiāng)再添農(nóng)業(yè)“芯片” 食用菌新品種授權(quán)數(shù)量全國(guó)第一_環(huán)球快報(bào)
- 當(dāng)前熱訊:2023年鄂爾多斯市農(nóng)村牧區(qū)供水工程已全部開工建設(shè)
- 已婚男同時(shí)交往5名女友,被發(fā)現(xiàn)后女友們聯(lián)合報(bào)警!長(zhǎng)沙檢察官公開征集線索
- 當(dāng)前最新:山西探索培養(yǎng)文物全科人才強(qiáng)化基層文保
- 雄安新區(qū)謀劃出海通道完善交通“微細(xì)血管”_每日時(shí)訊
- 車子放久了電瓶沒電了怎么啟動(dòng)(車子放久了電瓶沒電怎么辦)
- 天地源:前6月合約銷售金額59.8億元
- 保利置業(yè):前6月合約銷售金額374億元
- 平安不動(dòng)產(chǎn)180億元公司債券發(fā)行計(jì)劃獲通過
- 綠城中國(guó):前6月合約銷售金額1342億元_焦點(diǎn)日?qǐng)?bào)
- 燦瑞科技:公司磁傳感器、智能電機(jī)驅(qū)動(dòng)芯片等產(chǎn)品均可用于機(jī)器人上
- 女子稱自己患精神疾病兒子被游戲網(wǎng)友騙至緬北遭毆打,“再不去救,就要被賣到下家公司”,警方:已刑事立案
- 江蘇公布打擊整治網(wǎng)絡(luò)謠言10起典型案例
- 小米手機(jī)還原網(wǎng)絡(luò)設(shè)置
- 海通證券被北交所口頭警示 保薦代表人信息披露違規(guī)
- 午評(píng):指數(shù)延續(xù)震蕩調(diào)整 種植業(yè)與林業(yè)板塊強(qiáng)勢(shì)
- 奇點(diǎn)汽車被申請(qǐng)破產(chǎn)審查 燒光170億后迎來“至暗時(shí)刻”
- 標(biāo)的物履行條款是什么?標(biāo)的和標(biāo)的物可能是一個(gè)東西嗎?
- 提存期間標(biāo)的物孳息歸誰所有?標(biāo)的物意外滅失風(fēng)險(xiǎn)的承擔(dān)人是誰?
- 標(biāo)的物的風(fēng)險(xiǎn)負(fù)擔(dān)規(guī)則是什么?標(biāo)的物風(fēng)險(xiǎn)轉(zhuǎn)移的情況有哪兩種?
- 威海市商業(yè)銀行賦能“漁光互補(bǔ)”降減排 唱響“綠色興農(nóng)”協(xié)奏曲
- 金融期貨標(biāo)的物包括哪些工具?標(biāo)的物提存的法定情形有哪些?
- 城市維護(hù)建設(shè)稅計(jì)稅基數(shù)是什么?個(gè)人需要交城市維護(hù)建設(shè)稅嗎?
- 全球堅(jiān)果供應(yīng)鏈巨頭與三只松鼠在安徽合資建廠
- 我省將迎來入夏以來最強(qiáng)高溫天氣
- 盛洋科技終止向關(guān)聯(lián)方買中交科技 財(cái)務(wù)顧問為中天國(guó)富
- 應(yīng)交城市維護(hù)建設(shè)稅包括哪些?城市維護(hù)建設(shè)稅減半征收政策2023最新
- 城市維護(hù)建設(shè)稅屬于什么稅種?城市維護(hù)建設(shè)稅稅收優(yōu)惠政策有哪些?
- 【調(diào)研快報(bào)】蘇州科達(dá)接待信達(dá)證券等多家機(jī)構(gòu)調(diào)研
- 城市維護(hù)建設(shè)稅是什么意思?城市維護(hù)建設(shè)稅特征有哪些?城建費(fèi)有什么用途?
- 上半年中歐班列累計(jì)開行8641列
- 法定盈余公積可以彌補(bǔ)虧損嗎?法定盈余公積怎么提取?
- 法定盈余公積提取會(huì)計(jì)分錄怎么寫?法定盈余公積可以分配股利嗎?
- 法定盈余公積可以轉(zhuǎn)增資本嗎?法定盈余公積意思解釋
- 法定盈余公積必須提取嗎?法定盈余公積怎么計(jì)算?
- 美國(guó)男籃官方公布世界杯12人大名單
- 蘋果更新TestFlight應(yīng)用程序 支持visionOS和Apple Vision Pro
- 2023年云南日?qǐng)?bào)報(bào)業(yè)集團(tuán)公開招聘人員面試公告
- 鼎鎂科技IPO上會(huì)被否
- 鼎鎂科技IPO上會(huì)被否
- 合眾偉奇深交所上會(huì)被暫緩審議 保薦機(jī)構(gòu)為光大證券
- 中信銀行西安分行被罰 違反金融消費(fèi)權(quán)益保護(hù)管理規(guī)定
- 萬和科技終止北交所IPO 保薦機(jī)構(gòu)為安信證券
- 華鈺礦業(yè)7月7日盤中跌幅達(dá)5%
- 甘肅金昌:全面打造千億級(jí)新能源產(chǎn)業(yè)集群-天天熱文
- 全球即時(shí)看!愛樂匯交響樂團(tuán)《完全貝多芬》2023-2024 音樂季發(fā)布
- 信息:福州“小電驢”新規(guī)首日:從“報(bào)廢”到“上新”只需十幾分鐘
- 黑芝麻智能疑似深度綁定一汽,10輪融資后現(xiàn)金流僅夠維持24個(gè)月
- 廣州“三舊”改造實(shí)施辦法征求民意,突出保護(hù)樹木和歷史文化
- 可轉(zhuǎn)債新券再度暴漲 全部觸發(fā)盤中臨時(shí)停牌
- 齊齊哈爾市開展排水防澇應(yīng)急搶險(xiǎn)演練
- 大運(yùn)河文化帶建設(shè)高端智庫成立:讓大運(yùn)河“活”起來|環(huán)球觀熱點(diǎn)
- 四川啟動(dòng)培育第二批500家“千戶重點(diǎn)外貿(mào)企業(yè)”
- 馬斯克稱全面自動(dòng)駕駛將在今年年末到來
- 圓尾斗魚吃什么食物(圓尾斗魚壽命)
- 2023年蘭州城區(qū)普通高中錄取最低控制線確定
- 禾信儀器終止不超2.3億元可轉(zhuǎn)債 2021年上市募3.1億
- 廣合科技過會(huì):今年IPO過關(guān)第175家 民生證券過11單
- 基金分紅:富國(guó)純債債券發(fā)起式基金7月12日分紅
- 蘭州銀行:副行長(zhǎng)王毅任職資格獲批
- 人民幣兌美元中間價(jià)報(bào)7.2054 調(diào)升44個(gè)基點(diǎn)
- 今日上市:??菩略础⒅律锌萍?/a>
- 避暑消費(fèi)紅火 催熱“夏日經(jīng)濟(jì)”
- 西藏自治區(qū)黨委巡視組原副廳級(jí)巡視專員羅紅嚴(yán)重違紀(jì)違法被“雙開”
金融
財(cái)經(jīng)
要聞
公司
一到夏天,各種“硬核防曬”成了無數(shù)年輕人熱議的話題。在戶外街頭,越
詳細(xì)>>近日,第十一屆亞洲煉油和化工科技大會(huì)在山東煙臺(tái)舉行。記者在會(huì)上注意
詳細(xì)>>隨著暑期來臨,多個(gè)平臺(tái)數(shù)據(jù)顯示旅游市場(chǎng)進(jìn)一步“升溫”,在高溫天氣的
詳細(xì)>>文物全科人才畢業(yè)后直接到縣(市、區(qū))及以下文物保護(hù)事業(yè)單位定向就業(yè)
詳細(xì)>>今年,鄂爾多斯立足于全市資源型缺水、水質(zhì)型缺水、工程型缺水并存的實(shí)
詳細(xì)>>7月5日,新鄉(xiāng)市農(nóng)科院傳來喜訊,該院近日收到農(nóng)業(yè)農(nóng)村部頒發(fā)的21個(gè)植物
詳細(xì)>>