Closed4

Panda CSSのコードリーディング

いまきいれいまきいれ

大まかなコードリーディングの方針

  • panda codegenstyled-systemディレクトリが生成されるまでの流れの把握
    • コードが生成されるまでの主な登場人物の列挙
  • postcssプラグインでコードをパースしてcssを生成する流れの把握
  • コードをパースする部分の具体的なロジックの理解
  • styled.divがどうやって動いているのか
  • tokensの挙動の把握
  • variantsの挙動の把握
  • recipesの挙動の把握
  • 拡張の考察
    • descendantsへのスタイリングをテーマ定義する実現可能性
    • React Nativeへ応用できないか

読み解くのに助けになりそうな資料

Pandaの歴史
https://www.adebayosegun.com/blog/panda-css-the-origin-story

Stitches
variants APIの元ネタ
https://stitches.dev/

tailwindcss
コンパイラの元ネタ
https://tailwindcss.com/

いまきいれいまきいれ

panda codegenstyled-systemディレクトリが生成されるまでの流れの把握

愚直にcliでpanda codegenされてからの動きを追っていく
https://github.com/chakra-ui/panda/blob/17a193221c4e8ecbf48a24b4e5f471ad3cf8b2d7/packages/cli/src/cli-main.ts#L119

  • loadConfigAndCreateContextが呼ばれてPandaContextが作成される
  • codegenが実行される
  • PandaContextwatchConfigが呼ばれて、watcherが貼られる。watcherではファイル変更を監視してdiffを取得し、diffについてcodegenを実行してコードを再生成する

loadConfigAndCreateContext

  • loadConfigを実行してconfigのオブジェクトとconfigが依存しているパッケージを取得する
  • loadTsConfigを実行してtsconfig.jsonを読み込む、baseUrlpathsのようにコード生成に必要な情報は取得して使いやすい形にしておく
  • loadConfigloadTsConfigの結果からconfigのオブジェクトを作成し、それを渡してPandaContextをインスタンス化して返す

loadConfigの挙動

  • bundleNRequireを実行して、configファイルがdefault exportしているもの(configのオブジェクト)と、configファイルがインポートしているファイルを取得する

PandaContextとは

超絶ざっくり言うとGenerator(後述)にランタイムなどの環境情報を持たせたもの

codegen

  • 変更対象のArtifact(後述)を取得する。Artifactid(後述)が指定されている場合はそれらのみ。指定されていなければ全て取得する。
  • ArtifactについてOutputEnginewriteメソッドを実行し、生成ファイルの書き込みを行う

Artifactとは

コード生成物の区分の総称?デフォルトではstyled-systemディレクトリ以下に生成されるアレ
iddirfilesを持っている。

idは以下の定義

export type ArtifactId =
  | 'helpers'
  | 'keyframes'
  | 'design-tokens'
  | 'types'
  | 'css-fn'
  | 'cva'
  | 'sva'
  | 'cx'
  | 'create-recipe'
  | 'recipes'
  | 'recipes-index'
  | 'patterns'
  | 'patterns-index'
  | 'jsx-is-valid-prop'
  | 'jsx-helpers'
  | 'jsx-factory'
  | 'jsx-patterns'
  | 'jsx-patterns-index'
  | 'css-index'
  | 'themes'
  | 'package.json'
  | 'types-jsx'
  | 'types-entry'
  | 'types-styles'
  | 'types-conditions'
  | 'types-gen'
  | 'types-gen-system'
  | `recipes.${string}`
  | `patterns.${string}`

id毎にArtifactを生成する関数が用意されている。setupRecipes, setupPatterns, setupJsxTypes ...etc

それぞれの生成関数はconfigファイルのデータを読み取って、生成ファイルに書き込むコードを用意する。.jsコードと.d.tsコードを用意する。

いまきいれいまきいれ

コードが生成されるまでの登場人物の列挙

  • Config: panda.config.tsに書くやつ。そのままオブジェクトとして使われると思っていい。
  • PandaContext: Generatorに環境情報とかとかを持たせたもの
    • OutputEngineとかDiffEngineはインスタンス変数として持ってるんだけどDIはしてなくてコンストラクタの中で直接セットしてる = DIする形にすれば別のものを使える
  • Artifact: 生成されるコードのこと。コードの内容とどこに書き込むかの情報を持ってる。関数的にはConfig -> Artifact[]
  • OutputEngine: Artifactをファイルに書き込む具体的な方法を持っているやつ
    • (補足) PandaContextで使っているOutputEngineは普通にファイルに書き込むやつだけど、極端な話を言えばこれを差し替えればDBに生成物を保存できると思う。当然、そんなことする意味ないけど。
  • DiffEngine: Configの差分を変わったフィールドを取得するやつ。
いまきいれいまきいれ

postcssプラグインでコードをパースしてcssを生成する流れの把握

このスクラップは2024/10/05にクローズされました