banner
他山之石

他山之石

在React和TypeScript中使用emotion

本文介紹如何在 React 項目中使用 CSS in JS 方案:emotion。

image

emotion#

emotion 是一種高性能且靈活的 CSS-in-JS 庫。它本身與框架無關,你可以在 vue 或者 react 中搭配使用。目前我們使用的是 react,已經有多個項目在生產環境穩定運行。emotion11 是對 emotion10 的略微改進,主要側重於開發者的體驗,TS 的類型改進,以及使用新版本的解析器:Stylis。
本文主要介紹在 React 和 TypeScript 中如何集成 emotion11。

變化#

包重命名#

emotion11 最重要的變化之一是大部分面向用戶的 package 都已經重命名。

重命名包的列表:

  • @emotion/core → @emotion/react
  • emotion → @emotion/css
  • emotion-theming → moved into @emotion/react
  • emotion-server → @emotion/server
  • create-emotion → @emotion/css/create-instance
  • create-emotion-server → @emotion/server/create-instance
  • babel-plugin-emotion → @emotion/babel-plugin
  • eslint-plugin-emotion → @emotion/eslint-plugin
    jest-emotion → @emotion/jest

Hooks#

在內部使用鉤子以優化包的大小並在 React DevTools 中展示更好的 DOM 樹。

TypeScript#

TypeScript 類型已經被完全重寫。#
  1. 減少使用 emotion 時的構建時間,尤其是在大型項目中。
  2. 在許多情況下,不再需要為 emotion 組件手動指定通用參數
  3. 作為 props 的聯合類型得到了更好的支持,應該正確推斷
  4. 限制了 css 函數以防止傳遞無效的類型
  5. styled 的通用參數已更改,如果您指定 ComponentType,則需要刪除該通用參數
  6. styled 不再需要第二個參數 ExtraProps,代替地將其移動至 styled 調用之後。因此,styled<typeof MyComponent, ExtraProps>(MyComponent) 應該被改寫為 styled (MyComponent)({})
Theme 類型#

現在,為主題提供類型更加容易。您可以像這樣創建內置的 Theme 接口,而不是像以前那樣創建自定義實例:

css prop 類型#

基於使用的不同 JSX 運行時,emotion11 為 css prop 提供 TypeScript 支持的方式已經更改,可以僅對支持 className prop 的組件添加對應 css prop 的支持(因為 emotion 的 JSX 工廠函數採用提供的 css prop,對其解析並將生成的 className 傳遞給渲染的組件)。

Stylis V4#

emotion 使用的 css 解析器 Stylis 得到了升級,它修復了一些長期存在的解析邊緣情況,同時變得更小,更快。

Emotion 的緩存#

創建高速緩存的自定義實例時,現在需要 key 選項。請確保它是唯一的(並且不等於 “css”),因為它用於將樣式鏈接到緩存。如果多個緩存共享同一個鍵,它們可能會為彼此的樣式元素 “爭鬥”。 新的 prepend 選項可以使 Emotion 在指定 DOM 容器的開頭而不是結尾處添加樣式標籤。

使用#

安裝#

使用#

css prop#

emotion 提供主要的書寫 style 的方式是使用 css prop,它提供了一個簡潔靈活的 API 來對組件進行樣式設定。

有兩種方式使用 css prop:

Babel Preset#

Babel 預設可在使用 classic JSX 運行時自動啟用 Emotion 的 css prop。如果要使用新的 JSX 運行時,請不要使用此預設,而應使用 @emotion/babel-plugin

  • 安裝
  • 使用

.babelrc

如果您使用兼容的 React 版本(>=16.14.0),則可以通過以下配置選擇使用新的 JSX 運行時:

.babelrc

JSX Pragma#

在使用 CSS prop 的源文件頂部設置 jsx 編譯指示。此選項最適合測試 css prop 功能或在無法配置 babel 配置的項目(create-react-app,codesandbox 等)中。

與包含 linter 配置的註釋類似,此配置將 jsx babel 插件配置為使用 jsx 函數而不是 React.createElement。

如果您正在使用零配置工具來自動檢測應該使用哪個運行時(classic 還是 automatic),並且您已經在使用具有新 JSX 運行時的 React 版本(因此運行時為您自動配置了 runtime: 'automatic'),例如 Create React App 4,然後

編譯指示可能不起作用,您應該使用

使用 css prop#

主題#

Theme 包含在 @ emotion /react 包中。

將 ThemeProvider 添加到應用程序的頂層,並在樣式化組件中使用 props.theme 來訪問主題,或者提供一個接受該主題作為 css prop 的函數。

使用#

css function#
useTheme hook#

類型#

主題的類型需要在類型文件中聲明,否則 TS 類型會報錯。

types/emotion.d.ts

tsconfig.json

總結#

CSS in JS 的方案使用下來相比傳統的 less、sass 等優點的確不少,而 emotion 的類似方案也有很多,對我感受最深的一點是,打包速度提升很多,沒有冗餘的 CSS 出現,但是對於習慣了 css 寫法的人來說還是需要時間熟悉,總之,不妨一試。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。