Skip to content

Build-time Engine

只要記住一條規則,PikaCSS 就不難理解:styling engine 跑在 build 過程,不是在瀏覽器裡執行。

Zero runtime overhead 的意思就是字面上的意思

經過轉換後,正式環境的 bundle 裡只會留下靜態 class names 和產生的 CSS。頁面載入時,不會再有用戶端 styling engine 去解析 objects。

ts
// 原始碼:使用 pika() 定義樣式
// pika() 是全域函式,不需要另外匯入

const cardClass = pika({
	padding: '1.5rem',
	borderRadius: '0.75rem',
	boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
})

const titleClass = pika({
	fontSize: '1.25rem',
	fontWeight: '700',
	color: '#1a1a1a',
})

export function createCard(title: string, content: string) {
	return `
    <div class="${cardClass}">
      <h2 class="${titleClass}">${title}</h2>
      <p>${content}</p>
    </div>
  `
}
ts
// 編譯後,不會留下 pika 匯入,也不會有函式呼叫
// 最後只會剩下一般字串字面值

const cardClass = 'a b c'

const titleClass = 'd e f'

export function createCard(title: string, content: string) {
	return `
    <div class="${cardClass}">
      <h2 class="${titleClass}">${title}</h2>
      <p>${content}</p>
    </div>
  `
}
css
/* 由 @pikacss/unplugin-pikacss 自動產生 */

/* 唯一留在 runtime 的產物,就是這份靜態 CSS 檔 */
.pk-a { padding: 1.5rem; }
.pk-b { border-radius: 0.75rem; }
.pk-c { box-shadow: 0 2px 8px rgba(0,0,0,0.1); }
.pk-d { font-size: 1.25rem; }
.e { font-weight: 700; }
.pk-f { color: #1a1a1a; }

為什麼 engine 需要靜態輸入

build-time 架構帶來了幾個直接的好處:

  • deterministic output
  • atomic deduplication
  • generated autocomplete
  • 由 plugin 控制的 config resolution

但相對地,你也得用靜態的方式來表達變化,例如 variants、selectors、shortcuts 與 variables。

Virtual modules 與 generated files

pika.css 這個 import 是一個 virtual module。它會在 build-time 解析成產生的 CSS。在磁碟上,integration 也可能寫出像是 pika.gen.tspika.gen.css 這樣的檔案。

在把任何 generated artifacts 當成 source code 之前,建議先讀 Generated Files

正確的設計問題

不要問:「我要怎麼讓 pika() 接受這個 runtime value?」

要問的是:「我的專案應該用哪一種靜態表示法來編碼這個 styling 問題?」

很多時候,只要換成這個角度思考,最後得到的設計也會更好。

Next