PandaCSSをモノレポで使う
PandaCSSをモノレポでも使っていきたいと思います。
UIパッケージ側でPandaCSSをビルドしつつ、アプリケーションパッケージ側でそれを使い設定を記事に書いていきます。
モノレポ、マルチパッケージのプロジェクトを用意します。
uiパッケージにPandaCSSを準備する
uiパッケージにて次のインストールを行います。
インストールと初期設定
Panda CSSのインストール
npm i -D @pandacss/dev
Panda CSSの初期化を行います。
npx panda init --postcss
package.json
のscripts
に以下を追加します。
"prepare": "panda codegen"
src/index.cssを設定します。
@layer reset, base, tokens, recipes, utilities;
storybookの設定
preview.tsにimport "../src/index.css";を追加します。
import type { Preview } from "@storybook/react";
import "../src/index.css";
const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
},
},
},
};
export default preview;
インポートエイリアスの設定
Panda CSSで生成したスタイルシステムのインポートエイリアスを設定します。
tsconfig.jsonのpathsに"@s/*": ["./styled-system/*"]
を追加します。
"compilerOptions": {
...
"paths": {
"@/*": ["./src/*"],
"@s/*": ["./styled-system/*"]
}
...
}
vite.config.tsにも以下のようにエイリアスの設定を追加します。
import react from "@vitejs/plugin-react-swc";
import { defineConfig } from "vite";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
resolve: {
alias: [
{ find: "@/", replacement: `${__dirname}/src/` },
{ find: "@s/", replacement: `${__dirname}/styled-system/` },
],
},
});
スタイルをインポート先でも効くようにする
以上で、storybookにではcssが適用されているように見ることが出来るようになります。
しかしこのままですと、アプリケーションパッケージではcssが適用されません。
インポート先のでもスタイルが効くようにしていきます。
cssをビルドするコマンドを追加します。
{
"scripts": {
"prepare": "panda codegen && panda cssgen --outfile ./styled-system/styles.css",
"dev": "panda cssgen --outfile ./styled-system/styles.css -w",
"build": "panda cssgen --outfile ./styled-system/styles.css"
}
}
スタイルプロバイダーを作成します。
import "@s/styles.css"
export default function StyleProvider({children}: {children: React.ReactNode}) {
return children
}
あとは、作成したStyleProviderをアプリケーションパッケージに追加すれば、
スタイルが適応されるようになります。
開発時には、アプリケーションパッケージとUIパッケージの両方のdevコマンドを同時に実行します。ビルド時には、UIパッケージのbuildコマンドが先に実行されるようにCIのスクリプトを作成する必要があります。
npm workspace単体では自動で依存関係を見てくれないので、適切な順番になるようにスクリプトを作成するか、TurboRepoを導入するといいと思います。
Discussion