日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

你了解 JSX,那你了解 StyleX 么?

來源: 責編: 時間:2023-12-09 15:23:28 357觀看
導讀大家好,我卡頌。近日,Meta開源了一款「CSS-in-JS庫」 —— StyleX。看命名方式,Style - X是不是有點像JS - X,他們有關系么?當然有。JSX是一種「用JS描述HTML」的語法規范,廣泛應用于前端框架中(比如React、SolidJS...),由Meta

qId28資訊網——每日最新資訊28at.com

大家好,我卡頌。qId28資訊網——每日最新資訊28at.com

近日,Meta開源了一款「CSS-in-JS庫」 —— StyleX。看命名方式,Style - X是不是有點像JS - X,他們有關系么?當然有。qId28資訊網——每日最新資訊28at.com

JSX是一種「用JS描述HTML」的語法規范,廣泛應用于前端框架中(比如React、SolidJS...),由Meta公司提出。qId28資訊網——每日最新資訊28at.com

同樣的,按照Meta的設想,StyleX是一種「用JS描述CSS」的語法規范。qId28資訊網——每日最新資訊28at.com

早在React Conf 2019[1],Meta工程師「Frank」就介紹了這種Meta內部使用的「CSS-in-JS庫」。qId28資訊網——每日最新資訊28at.com

qId28資訊網——每日最新資訊28at.com

從Meta內部使用,到大會對外宣傳,這期間肯定已經經歷大量內部項目的洗禮。而從做完宣傳到最終開源,又經歷了快5年時間。qId28資訊網——每日最新資訊28at.com

那么,這款Meta出品、打磨這么長時間的「CSS-in-JS庫」,到底有什么特點呢?qId28資訊網——每日最新資訊28at.com

本文讓我們來聊聊。qId28資訊網——每日最新資訊28at.com

為什么需要CSS解決方案

市面上有非常多「CSS解決方案」,比如:qId28資訊網——每日最新資訊28at.com

  • BEM命名規范
  • CSS Module規范
  • 原子CSS(比如TailwindCSS)
  • CSS-in-JS(比如emotion)

為什么需要這些方案?原生CSS哪里不好?在這里,我們舉個小例子(例子來源于「React Conf 2019」)。考慮如下代碼:qId28資訊網——每日最新資訊28at.com

CSS文件如下:qId28資訊網——每日最新資訊28at.com

.blue {color: blue;}.red {color: red;}

HTML文件如下:qId28資訊網——每日最新資訊28at.com

<p class="red blue">我是什么顏色?</p>

請問p標簽是什么顏色的?qId28資訊網——每日最新資訊28at.com

從class來看,blue在red后面,p應該是藍色的么?qId28資訊網——每日最新資訊28at.com

實際上,樣式取決于他們在樣式表中定義的順序,.red的定義在.blue后面,所以p應該是紅色的。qId28資訊網——每日最新資訊28at.com

是不是已經有點暈了?再增加點難度。如果.red和.blue分別在兩個文件中定義呢?qId28資訊網——每日最新資訊28at.com

# css文件1.blue {color: blue;}
# css文件2.red {color: red;}

那p的樣式就取決于最終打包代碼中樣式文件的加載順序。qId28資訊網——每日最新資訊28at.com

上面只是原生CSS中「選擇器優先級相關的一個缺陷」(除此外還有其他缺陷,比如「作用域缺失」...)。隨著項目體積增大、項目維護時間變長、項目維護人員更迭,這些缺陷會被逐漸放大。qId28資訊網——每日最新資訊28at.com

正是由于這些原因,才出現了各種「CSS解決方案」。qId28資訊網——每日最新資訊28at.com

StyleX的基本使用

StyleX的API很少,掌握下面兩個就能上手使用:qId28資訊網——每日最新資訊28at.com

  • stylex.create,創建樣式。
  • stylex.props,定義props。

比如:qId28資訊網——每日最新資訊28at.com

import * as stylex from 'stylex';// 創建樣式const styles = stylex.create({  red: {color: 'red'},});// 定義propsconst redStyleProps = stylex.props(styles.red);

使用時:qId28資訊網——每日最新資訊28at.com

<div {...redStyleProps}>文字顏色是紅色</div>

stylex是如何解決上面提到的red blue優先級問題呢?其實很簡單,考慮如下代碼:qId28資訊網——每日最新資訊28at.com

import * as stylex from 'stylex';// 創建樣式const styles = stylex.create({  red: {color: 'red'},  blue: {color: 'blue'}});// 使用<p {...styles.props(styles.red, styles.blue)}></p>

樣式的優先級只需要考慮styles.props中的定義順序(blue在red后面,所以顏色為blue),不需要考慮樣式表的存在。qId28資訊網——每日最新資訊28at.com

有些同學會說,看起來和常見的CSS-in-JS沒啥區別啊。那stylex相比于他們的優勢是啥呢?qId28資訊網——每日最新資訊28at.com

相比其他CSS-in-JS的優勢

首先要明確,stylex雖然以CSS-in-JS的形式存在,但本質上他是一種「用JS描述CSS的規范」。文章開頭也提到,他的定位類似JSX。qId28資訊網——每日最新資訊28at.com

既然是規范,那他就不是對CSS的簡單封裝、增強,而是一套「自定義的樣式編寫規范」,只不過這套規范最終會被編譯為CSS。qId28資訊網——每日最新資訊28at.com

作為對比,Less、Sass這樣的「CSS預處理器」就是對CSS語法的封裝、增強qId28資訊網——每日最新資訊28at.com

那么,stylex都有哪些規范呢?qId28資訊網——每日最新資訊28at.com

比如,stylex鼓勵將樣式與組件寫在同一個文件,類似Vue的SFC(單文件組件)。這么做除了讓組件的樣式與邏輯更方便維護,也減少了stylex編譯的實現難度。qId28資訊網——每日最新資訊28at.com

再比如,CSS中各種選擇器的復雜組合增強了選擇器的靈活性。但同時也增強了不確定性。舉個例子,考慮如下三個選擇器:qId28資訊網——每日最新資訊28at.com

  • .className > *
  • .className ~ *
  • .className:hover > div:first-child

這些對.className應用的選擇器將影響.className的某些后代。當這樣的選擇器多了后,很可能會在開發者不知道的情況下改變某些后代元素的樣式。qId28資訊網——每日最新資訊28at.com

遇到這種情況我們一般會怎么處理呢?正確的選擇當然是找到上述影響后代的選擇器,再修改他。qId28資訊網——每日最新資訊28at.com

但大家工作都這么忙,遇到這種問題,多半就是用新的選擇器覆寫樣式,必要的時候還會加!important后綴。久而久之,這代碼就沒法維護了。qId28資訊網——每日最新資訊28at.com

為了規避這種情況,在stylex中,除了「可繼承樣式」(指「當父元素應用后,子孫元素默認會繼承的樣式」,比如color)外,不支持這些「可以改變子孫后代樣式的選擇器」。qId28資訊網——每日最新資訊28at.com

那我該如何讓子孫組件獲得父組件同樣的樣式呢?通過props透傳啊~qId28資訊網——每日最新資訊28at.com

也就是說,stylex禁用了CSS中可能造成混淆的選擇器,用JS的靈活性彌補這部分功能的缺失。qId28資訊網——每日最新資訊28at.com

有些同學可能會說:這些功能,其他「CSS-in-JS庫」也能做啊。qId28資訊網——每日最新資訊28at.com

這就要談到「CSS-in-JS庫」最大的劣勢 —— 為了計算出最終樣式,在運行時會造成額外的樣式計算開銷。qId28資訊網——每日最新資訊28at.com

stylex通過編譯來減少運行時的開銷。比如對于上面提到過的stylex的代碼:qId28資訊網——每日最新資訊28at.com

import * as stylex from 'stylex';// 創建樣式const styles = stylex.create({  red: {color: 'red'},});// 定義propsconst redStyleProps = stylex.props(styles.red);

編譯后的產物包括如下兩部分:qId28資訊網——每日最新資訊28at.com

JS的編譯產物:qId28資訊網——每日最新資訊28at.com

import * as stylex from 'stylex';const redStyleProps = {className: 'x1e2nbdu'};

CSS的編譯產物:qId28資訊網——每日最新資訊28at.com

.x1e2nbdu {  color: red;}

所以,運行時實際運行的代碼始終為:qId28資訊網——每日最新資訊28at.com

<div {...{className: 'x1e2nbdu'}}>...</div>

對于再復雜的樣式,stylex都會通過編譯生成「可復用的原子類名」。qId28資訊網——每日最新資訊28at.com

即使是跨文件使用樣式,比如我們在另一個文件也定義個使用color: 'red'樣式的stylex屬性foo:qId28資訊網——每日最新資訊28at.com

import * as stylex from '@stylexjs/stylex';const styles = stylex.create({  foo: {    color: 'red',  },  bar: {    backgroundColor: 'blue',  },});

會得到如下編譯結果,其中x1e2nbdu是一個原子類名,他是上一個文件中styles.red的編譯產物:qId28資訊網——每日最新資訊28at.com

import * as stylex from '@stylexjs/stylex';const styles = {  foo: {    color: 'x1e2nbdu',    $$css: true,  },  bar: {    backgroundColor: 'x1t391ir',    $$css: true,  },};

隨著項目體積增大,樣式表的體積也能控制在合理的范圍內。這種對原子類名的控制粒度是其他「CSS-in-JS庫」辦不到的。qId28資訊網——每日最新資訊28at.com

相比于原子CSS的優勢

stylex相比TailwindCSS這樣的原子CSS有什么優勢呢?qId28資訊網——每日最新資訊28at.com

這就要談到原子CSS的一個特點 —— 使用約定好的字符串實現樣式。比如,使用TailwindCSS定義圖片的樣式:qId28資訊網——每日最新資訊28at.com

<img class="w-24 h-24 rounded-full mx-auto" src="/sarah-dayan.jpg" alt="" width="384" height="512">

效果如下:qId28資訊網——每日最新資訊28at.com

qId28資訊網——每日最新資訊28at.com

由于樣式都是由不同的「原子類名字符串」組合而成,TS沒法分析,這就沒法實現「樣式的類型安全」。qId28資訊網——每日最新資訊28at.com

什么叫「樣式的類型安全」?通俗的講,如果我實現一個組件,組件通過style props定義樣式,我只希望使用者能夠改變color與fontSize兩個樣式屬性,不能修改其他屬性。如果能實現這一點,就是「樣式的類型安全」。qId28資訊網——每日最新資訊28at.com

「樣式的類型安全」有什么意義呢?舉個例子:設想開發基礎組件庫的團隊使用stylex。那么當業務團隊使用該組件庫時,就只能自定義組件的一些樣式(由組件庫團隊約束)。qId28資訊網——每日最新資訊28at.com

當基礎組件庫升級時,組件庫團隊能很好對組件樣式向下兼容(因為知道只有哪些樣式允許被修改)。qId28資訊網——每日最新資訊28at.com

在stylex中,由于stylex.create的產物本質是對象,所以我們可以為每個產物定義類型聲明。比如在如下代碼中,我們限制了組件style props只能接受如下stylex樣式:qId28資訊網——每日最新資訊28at.com

import type {StyleXStyles} from '@stylexjs/stylex';type Props = {  // ...  style?: StyleXStyles<{    color?: string;    backgroundColor?: string;    borderColor?: string;    borderTopColor?: string;    borderEndColor?: string;    borderBottomColor?: string;    borderStartColor?: string;  }>;};

總結

我猜想,當更多人知道stylex后,他會收到比當初TailwindCSS火時更多的兩級分化的評價。qId28資訊網——每日最新資訊28at.com

畢竟,stylex的設計初衷是為了解決Meta內部復雜應用的樣式管理。如果:qId28資訊網——每日最新資訊28at.com

  • 你項目沒有達到Meta這樣的體量
  • 你項目沒有多年的迭代周期
  • 你項目前前后后沒有多個工程師經手

那大概率是不能接受stylex設計理念中的這些約束。qId28資訊網——每日最新資訊28at.com

對于stylex,你怎么看?qId28資訊網——每日最新資訊28at.com

參考資料

[1]React Conf 2019:https://www.youtube.com/watch?v=9JZHodNR184&t=270s。qId28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-40682-0.html你了解 JSX,那你了解 StyleX 么?

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: B站邊緣網絡四層負載均衡器的探索與應用

下一篇: MySQL數據庫壓力測試與性能評估方法:Java實戰

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 卓尼县| 桃江县| 栖霞市| 登封市| 永定县| 漯河市| 巴彦淖尔市| 盐边县| 双牌县| 翁牛特旗| 科尔| 井冈山市| 旬阳县| 邯郸市| 淮滨县| 太原市| 阿城市| 柯坪县| 威宁| 蛟河市| 三明市| 鄂托克前旗| 原阳县| 西平县| 柘荣县| 朝阳市| 华池县| 延长县| 昭平县| 镇平县| 迁安市| 大新县| 湘乡市| 大埔县| 嵊州市| 秦皇岛市| 田东县| 清涧县| 临泉县| 泸西县| 昭觉县|