Turborepo と shadcn を使った React + Vite プロジェクトの構築ガイド
React アプリケーションに shadcn を統合し、さらに Turborepo のセットアップで実現したい状況に直面されたのですね。あるいは、将来的に使用することを計画して情報を得たいのかもしれません。いずれにせよ、適切な場所にたどり着きました。この記事では、そのようなセットアップに最適な構造と、実装時によくある落とし穴について説明します。
コードを直接確認したい場合は、こちらです。役立つと感じた場合は、ぜひスター🌟をつけてください。
それでは、詳細な手順をみていきましょう。
新しい Turborepo のセットアップ
pnpm dlx create-turbo@latest
私の Turborepo の名前とパッケージマネージャーの選択は、それぞれ vite-shadcn-turborepo と pnpm workspaces でした。他のオプションを選択しても、問題なく以下の手順に従うことができるはずです。
デフォルトでは、Turborepo は apps ディレクトリに 2 つの Nextjs アプリケーションを提供し、packages 内に ui パッケージも含まれています。ここでは、apps 内に独自の React+Vite アプリケーションをセットアップし、ui パッケージ内に shadcn/ui を設定します。そのために、既存のボイラープレートコードを削除してクリーンアップしましょう。
Vite を使用した React アプリのセットアップ
apps ディレクトリ内の apps/docs と apps/web フォルダを削除した後、新しい Vite+React アプリを以下のコマンドで作成します:
cd apps
pnpm create vite
コマンド実行後の私の選択肢は以下の通りでした:
✔ プロジェクト名: … vite-project
✔ フレームワークの選択: › React
✔ バリアントの選択: › TypeScript + SWC
すべてが予想通りに進んだ場合、以下のコマンドを実行できるはずです:
pnpm install
pnpm run dev
これで、アプリケーションが http://localhost:5173/ で実行されているはずです。
🎉 おめでとうございます。Turborepo セットアップで Vite+React アプリを正常に実行できました。
shadcn/ui の統合
次に、shadcn/ui の部分に移ります。ここまでのように単純ではないかもしれません。shadcn を ui パッケージに配置するように Turborepo を設定します。
まず、ui パッケージに tailwindcss を追加し、次のコマンドを使用して ui パッケージ内で shadcn/ui を初期化します。
その前に、Turborepo のボイラープレートから不要な部分を取り除くために ui フォルダをクリーンアップしましょう。ui フォルダは以下のようになるはずです:
-ui
|-src
|-.eslintrc.js
|-package.json
|-tsconfig.json
ここで、pnpm を使用し、ts と Turborepo セットアップを利用しているため、tailwindcss のドキュメントに従って少し修正を加えます。
pnpm --filter ui install -D tailwindcss postcss autoprefixer
cd packages/ui
pnpm dlx tailwindcss init
ドキュメントに従って、postcss.config.js も以下の内容で作成します:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}
次に、main.css ファイルを以下の内容で作成します:
@tailwind base;
@tailwind components;
@tailwind utilities;
shadcn コンポーネントと utils が機能するようにエイリアスを設定します。shadcn/ui では、コンポーネントが他のコンポーネントと utils をインポートできるようにエイリアスを設定する必要があります。そのために tsconfig.json ファイルを以下のように修正します:
{
"extends": "@repo/typescript-config/react-library.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@ui/*": ["./src/*"]
}
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
ここでは、src ディレクトリを参照するためにエイリアスを使用しています。
次に、shadcn のドキュメントに従ってコンポーネントをセットアップします。以下のコマンドを実行します:
pnpm dlx shadcn-ui@latest init
shadcn/ui はセットアップを完了するためにいくつかの質問をします。私の選択は以下の通りでした:
✔ TypeScript を使用しますか(推奨)? … はい
✔ どのスタイルを使用しますか? › デフォルト
✔ ベースカラーとしてどの色を使用しますか? › Slate
✔ グローバル CSS ファイルはどこにありますか? … main.css
✔ 色に CSS 変数を使用しますか? … はい
✔ カスタム tailwind プレフィックス(例:tw-)を使用していますか?(使用していない場合は空白のままにしてください) …
✔ tailwind.config.js はどこにありますか? … tailwind.config.js
✔ コンポーネントのインポートエイリアスを設定してください: … @ui/components
✔ utils のインポートエイリアスを設定してください: … @ui/lib/utils
✔ React Server Components を使用していますか? … いいえ
✔ components.json に設定を書き込みます。続行しますか? … はい
この時点で、postcss.config.js、tailwind.config.js、あるいは src/lib/utils.ts などのファイルで eslint 関連のエラーが発生している場合、それは tslint.config.json ファイルを削除したにもかかわらず、.eslintrc.js で必要とされているためです。今のところ、該当する行を削除して、新しい .eslintrc.js を以下のようにします:
/**@type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@repo/eslint-config/react-internal.js"],
parser: "@typescript-eslint/parser",
};
これが完了したら、以下のコマンドを使用して最初の shadcn コンポーネントを追加しましょう:
pnpm dlx shadcn-ui@latest add button
また、すべてのコンポーネントをバレルエクスポートするために、ui/src/components に index.ts ファイルを作成します。
現時点では以下のようになります:
export * from "./ui/button";
次に、ui からすべてを適切にエクスポートするために、package.json の exports を以下のように修正します:
"exports": {
".": "./src/components/index.ts",
"./main.css":"./main.css",
"./postcss.config": "./postcss.config.js",
"./tailwind.config": "./tailwind.config.js",
"./lib/*": "./src/lib/*.ts"
}
これらの手順をすべて完了すると、以下のようなファイル構造になるはずです:
-ui
|-node_modules
|-src
| |-components
| | |-ui
| | | |-button.tsx
| | |-index.ts
| |-lib
| | |-utils.ts
|-.eslintrc.js
|-components.json
|-main.css
|-package.json
|-postcss.config.js
|-tailwind.config.js
|-tsconfig.json
ui パッケージの使用
packages/ui での作業が完了したので、apps/vite-project に移動して、実際にボタンコンポーネントを使用します。dependencies 内の package.json に以下の行を追加します:
{
"dependencies": {
+ "@repo/ui": "workspace:*"
}
}
また、index.css や App.css などの含まれているすべての css ファイルを削除し、それらのインポート文も削除しましょう。
これで、プロジェクトのルートで pnpm install を実行した後、ボタンコンポーネントを使用する準備が整いました。App.tsx では以下のようになります:
import { Button } from "@repo/ui";
function App() {
return <Button>MyButton</Button>;
}
export default App;
pnpm run dev を実行すると、ボタンが表示されるはずですが、待ってください!スタイルが適用されていません。以下のコマンドでそれを修正しましょう:
pnpm --filter vite-project install -D tailwindcss postcss autoprefixer
cd apps/vite-project
pnpm dlx tailwindcss init
お気づきかもしれませんが、Turborepo に tailwindcss をインストールして初期化しています。次に、tailwind.config.js を以下のように修正します:
export * from "@repo/ui/tailwind.config"
そして、postcss.config.js を以下のように作成します:
export { default } from "@repo/ui/postcss.config";
これらの変更の後、main.tsx で ui パッケージから main.css ファイルを単純にインクルードします:
import "@repo/ui/main.css";
これらの変更により、ウェブアプリケーションで shadcn のスタイルが適用されたボタンが表示されるはずです。また、tailwindcss を使用して vite+React アプリのレイアウトとスタイルを設定することもできます。
ビルドの問題への対処
最後に、pnpm run build を試みると、エイリアスされたパスを認識できないため tsc がエラーをスローします。これを緩和するために、vite.config.ts で行ったように、tsconfig.json の compilerOptions 内にエイリアスを追加します:
{
"compilerOptions": {
+ "baseUrl": ".",
+ "paths": {
+ "@ui/*": ["../../packages/ui/src/*"]
+ },
}
これで、アプリの構築が可能になりました。
再度、完全なコードリポジトリはここで確認できます。
読んでいただき、ありがとうございました!
この記事は、2024年2月に弊社のエンジニア Binabh Devkota が執筆した内容を日本語に翻訳したものです。
英語版はこちらをご覧ください。
https://articles.wesionary.team/react-vite-with-shadcn-ui-for-ui-components-all-in-turborepo-8af3deafa58e
採用情報
私たちはプロダクト共創の仕組み化に取り組んでいます。プロダクト共創をリードするプロダクト・マネージャー、そして、私たちのビジョンを市場に届ける営業メンバーを募集しています!
開発パートナーをお探しの企業様へ
弊社は、グローバル開発のメリットを活かし、高い費用対効果と品質を両立しています。経験豊富で多様性のあるチームが、課題を正しく理解し、最適なシステムと優れた体験を実現します。業務システムの開発、新規事業の開発、業務効率化やDX化に関するお困りごと、ぜひ弊社にご相談ください。