Nx で shadcn/ui
参考記事 How to get started with shadcn/ui and Next.js within a Nx Monorepo
概要
前提
Nx ワークスペースがあり、web という名前の Next.js プロジェクトがあること
パッケージをインストール
Manual Installation の手順にある必要なパッケージをインストールする:
npm install tailwindcss-animate class-variance-authority clsx tailwind-merge
npm install lucide-react
shadcn/ui をセットアップ
shadcn/ui の components.json をルートに作成する:
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "default",
"rsc": false,
"tailwind": {
"config": "libs/web/ui/src/tailwind.config.js",
"css": "libs/web/ui/src/globals.css",
"baseColor": "stone",
"cssVariables": true
},
"aliases": {
"components": "libs/web/ui/src",
"utils": "@libs/web-ui-util"
}
}
※ rsc を true にすると use client が自動で入る
shadcn/ui cli を使えるようにするために tsconfig.json
を作成
これを作成しておかないと Failed to load tsconfig.json. Couldn't find tsconfig.json
とおこられてしまう
{
"_COMMENT": "only used by shadcn/ui cli to generate shadcn/ui components",
"extends": "./tsconfig.base.json"
}
web-ui ライブラリを作成
コンポーネントを置くために web-ui ライブラリを作る
@nx/next:library で生成し、不要なものを削除する
$ nx g @nx/next:library web-ui --directory=libs/web/ui --style=none --importPath=@libs/web-ui
> NX Generating @nx/next:library
✔ What should be the project name and where should it be generated? · web-ui @ libs/web/ui
UPDATE nx.json
UPDATE package.json
UPDATE .gitignore
CREATE libs/web/ui/project.json
CREATE libs/web/ui/.eslintrc.json
CREATE libs/web/ui/README.md
CREATE libs/web/ui/src/index.ts
CREATE libs/web/ui/tsconfig.lib.json
CREATE libs/web/ui/tsconfig.json
CREATE libs/web/ui/src/lib/web-ui.spec.tsx
CREATE libs/web/ui/src/lib/web-ui.tsx
UPDATE tsconfig.base.json
CREATE libs/web/ui/src/server.ts
CREATE libs/web/ui/src/lib/hello-server.tsx
不要なものを削除:
- libs/web/ui/src/lib
- libs/web/ui/src/server.ts
- libs/web/ui/src/index.ts
{
"compilerOptions": {
"paths": {
- "@libs/web-ui/server": ["libs/web/ui/src/server.ts"]
Tailwind CSS の設定ファイルを作成する
content だけ shadcn/ui のドキュメントの tailwind.config.js と変更する:
const { fontFamily } = require('tailwindcss/defaultTheme');
/** @type {import('tailwindcss').Config} */
module.exports = {
darkMode: ['class'],
- content: ["app/**/*.{ts,tsx}", "components/**/*.{ts,tsx}"],
+ content: [
+ './{app,components}/**/*.{ts,tsx}',
+ '../../libs/web/ui/src/ui/**/*.{ts,tsx}',
+ ],
省略
ドキュメント Configure styles の通りに libs/web/ui/src/globals.css
を作成する
web-ui-util ライブラリを作成
cn 関数を置くために web-ui-util ライブラリを作る
@nx/js:library で生成し、不要なものを削除する
nx g @nx/js:library web-ui-util --directory=libs/web/ui-util --bundler=swc --unitTestRunner=none --importPath=@libs/web-ui-util
> NX Generating @nx/js:library
✔ What should be the project name and where should it be generated? · web-ui-util @ libs/web/ui-util
CREATE libs/web/ui-util/tsconfig.json
CREATE libs/web/ui-util/README.md
CREATE libs/web/ui-util/src/index.ts
CREATE libs/web/ui-util/src/lib/web-ui-util.ts
CREATE libs/web/ui-util/tsconfig.lib.json
CREATE libs/web/ui-util/.swcrc
CREATE libs/web/ui-util/package.json
CREATE libs/web/ui-util/project.json
CREATE libs/web/ui-util/.eslintrc.json
UPDATE tsconfig.base.json
不要なものを削除:
- libs/web/ui-util/src/lib
パスマッピングを修正:
{
"compilerOptions": {
"paths": {
- "@libs/web-ui": ["libs/web/ui/src/index.ts"],
+ "@libs/web-ui/*": ["libs/web/ui/src/ui/*"],
index.ts
に Add a cn helper の cn 関数を定義しエクスポートする:
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
web プロジェクトをセットアップ
以下の内容で globals.css
を作成する
@import '../../../libs/web/ui/src/globals.css';
@nx/react:setup-tailwind を使って Tailwind CSS をセットアップする
nx g setup-tailwind --project=web
このコマンドを実行すると、以下パッケージのインストールがされ、設定ファイルが生成される
"devDependencies": {
+ "autoprefixer": "10.4.13",
+ "postcss": "8.4.21",
+ "tailwindcss": "3.2.7",
+ apps/web/postcss.config.js
+ apps/web/tailwind.config.js
postcss.config.js
const { join } = require('path');
// Note: If you use library-specific PostCSS/Tailwind configuration then you should remove the `postcssConfig` build
// option from your application's configuration (i.e. project.json).
//
// See: https://nx.dev/guides/using-tailwind-css-in-react#step-4:-applying-configuration-to-libraries
module.exports = {
plugins: {
tailwindcss: {
config: join(__dirname, 'tailwind.config.js'),
},
autoprefixer: {},
},
};
tailwind.config.js については以下のように web-ui ライブラリの設定ファイルを読み込むよう書き換える:
const TailwindConfig = require('../../libs/web/ui/src/tailwind.config');
module.exports = {
...TailwindConfig,
};
補足
Dependency npm:postcss:8.4.21 is vulnerable, safe version 8.4.31
のワーニングが出ていたので npm i postcss@8.4.31
を実行。
以上ですべてのセットアップは完了
試しにコンポーネントを作成
npx shadcn-ui@latest add skeleton
を実行すると component.json
の aliases.components で設定したディレクトリ libs/web/ui/src
に ui/skelton.tsx
が作成される
作成されたコンポーネント
cn 関数のインポート元のパス @libs/web-ui-util
は component.json
の aliases.utils で設定したパスになる
import { cn } from '@libs/web-ui-util';
function Skeleton({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) {
return (
<div
className={cn('animate-pulse rounded-md bg-muted', className)}
{...props}
/>
);
}
export { Skeleton };
これで web プロジェクト内で Skeleton コンポーネントが使えるようになる
import { Skeleton } from '@libs/web-ui/skeleton';
Discussion