Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed .github/workflows/.gitkeep
Empty file.
72 changes: 72 additions & 0 deletions .github/workflows/chromatic.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
name: 'Chromatic Publish'

on:
pull_request:
branches:
- develop

permissions: write-all
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

권한 축소(least-privilege) 권장: write-all 제거하고 필요한 권한만 명시

PR 코멘트 작성과 체크아웃/Chromatic 상태 보고에 필요한 최소 권한만 부여하세요.

아래처럼 축소를 제안합니다(Chromatic 체크런 생성이 필요하면 checks: write 추가).

-permissions: write-all
+permissions:
+  contents: read
+  pull-requests: write
+  # Chromatic가 체크런/상태 리포트를 생성한다면 아래도 고려
+  # checks: write
🤖 Prompt for AI Agents
In .github/workflows/chromatic.yml around line 8, remove the broad "permissions:
write-all" and replace it with least-privilege permissions required for the
workflow: grant contents: read for checkout, pull-requests: write (or issues:
write) only if the workflow must post PR comments, and add checks: write only if
Chromatic needs to create or update GitHub Checks; ensure no other write
permissions are granted so the workflow runs with minimal privileges.


jobs:
storybook:
runs-on: ubuntu-latest

steps:
- name: Checkout Repository
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20

- name: Install PNPM
run: npm i -g pnpm

Comment on lines +20 to +27
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

PNPM 설치 방식 개선 및 캐시 연계

npm -g 설치 대신 공식 액션을 사용하고 Node 세팅에 PNPM 캐시를 연동하세요.

 - name: Setup Node.js
   uses: actions/setup-node@v4
   with:
     node-version: 20
+    cache: pnpm
+
-      - name: Install PNPM
-        run: npm i -g pnpm
+      - name: Setup PNPM
+        uses: pnpm/action-setup@v4
+        with:
+          version: 9
+          run_install: false

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In .github/workflows/chromatic.yml around lines 20 to 27, the workflow installs
PNPM with a global npm install and doesn't tie PNPM to the Node setup cache;
replace the global install with the official PNPM setup action and enable PNPM
caching on the Node setup step. Change the Node setup step to include cache:
'pnpm' and remove the "npm i -g pnpm" run step, instead add the official action
for PNPM (pnpm/action-setup) immediately after setup-node so PNPM is installed
via the action and benefits from the cache integration.

- name: Cache node modules
id: cache-node
uses: actions/cache@v3
with:
path: |
**/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-node-

Comment on lines +28 to +37
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

actions/cache@v3 런타임 호환성 이슈 및 캐시 전략 재고(PNPM 스토어 캐시 권장)

actionlint 경고대로 v3는 최신 러너와 호환되지 않습니다. 또한 PNPM은 node_modules 캐시보다 스토어 캐시(~/.pnpm-store)를 쓰는 것이 안전/효율적입니다.

  • 최소 수정(버전 업):
-        uses: actions/cache@v3
+        uses: actions/cache@v4
  • 권장 수정(수동 node_modules 캐시 제거, setup-node의 cache: pnpm로 일원화):
-      - name: Cache node modules
-        id: cache-node
-        uses: actions/cache@v3
-        with:
-          path: |
-            **/node_modules
-          key: ${{ runner.os }}-node-${{ hashFiles('**/pnpm-lock.yaml') }}
-          restore-keys: |
-            ${{ runner.os }}-node-
+      # PNPM 스토어 캐시는 actions/setup-node@v4의 `cache: pnpm`가 관리

선택지 중 하나로 정리해 주세요(권장: 후자).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Cache node modules
id: cache-node
uses: actions/cache@v3
with:
path: |
**/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-node-
# PNPM 스토어 캐시는 actions/setup-node@v4의 `cache: pnpm`가 관리
🧰 Tools
🪛 actionlint (1.7.7)

30-30: the runner of "actions/cache@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
.github/workflows/chromatic.yml lines 28-37: actions/cache@v3 has runtime
compatibility warnings and PNPM works better caching its store than
node_modules; provide two options: minimal fix—bump to actions/cache@v4 (or the
latest compatible tag) and keep existing path/key, ensuring actionlint warnings
are resolved; recommended fix—remove manual node_modules caching, switch to
setup-node cache: 'pnpm' (or use pnpm/setup-node with cache support) and/or add
explicit ~/.pnpm-store path to cache, update keys to include pnpm-lock.yaml and
runner.os, and remove the duplicate node_modules pattern so caching is
centralized and PNPM store is used.

- name: Install Dependencies
if: steps.cache-node.outputs.cache-hit != 'true'
run: pnpm install --frozen-lockfile

- name: Build Storybook for design system(pds)
run: pnpm --filter @pinback/design-system run build:storybook

- name: Publish to Chromatic
id: chromatic
uses: chromaui/action@latest
with:
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
workingDir: packages/design-system
buildScriptName: build:storybook
onlyChanged: true
autoAcceptChanges: true
exitOnceUploaded: true

- name: Comment PR on Success
if: success() && github.event_name == 'pull_request'
uses: thollander/actions-comment-pull-request@v2
with:
comment_tag: ${{ github.event.number }}-storybook
message: |
✅ Storybook chromatic 배포 확인:
🐿️ [storybook](${{ steps.chromatic.outputs.storybookUrl }})

- name: Comment PR on Failure
if: failure() && github.event_name == 'pull_request'
uses: thollander/actions-comment-pull-request@v2
with:
comment_tag: ${{ github.event.number }}-storybook
message: |
🚨 Storybook 배포 실패
: Github Actions 로그를 확인해주세요.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ yarn-error.log*
# typescript
# 증분 빌드 정보 파일
*.tsbuildinfo

*storybook.log
storybook-static
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@
"tailwindCSS.suggestions": true,
"editor.quickSuggestions": {
"strings": true
}
},
"tailwindCSS.experimental.configFile": "./packages/design-system/styles.css"
Comment on lines +20 to +21
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Tailwind VS Code 설정: configFile이 CSS를 가리키고 있어 인텔리센스가 비활성화될 수 있음

tailwindCSS.experimental.configFile에는 Tailwind 설정 파일(tailwind.config.{ts,js,cjs,mjs})을 지정해야 합니다. 현재 styles.css를 가리키고 있어 확장 기능이 테마/플러그인/콘텐츠(globs)를 로드하지 못하고, Storybook/디자인 시스템 작업 시 클래스 제안·진단이 제대로 동작하지 않을 수 있습니다. 설계 의도대로라면 packages/design-system/tailwind.config.ts(또는 해당 패키지의 실제 설정 파일)로 변경해 주세요.

적용 제안(diff):

   "editor.quickSuggestions": {
     "strings": true
   },
-  "tailwindCSS.experimental.configFile": "./packages/design-system/styles.css"
+  "tailwindCSS.experimental.configFile": "./packages/design-system/tailwind.config.ts"
 }

여러 패키지에 Tailwind 설정이 추가될 가능성이 있다면(모노레포), 배열 형태로 다중 설정을 지원하도록 확장하는 것도 고려해 주세요:

-  "tailwindCSS.experimental.configFile": "./packages/design-system/tailwind.config.ts"
+  "tailwindCSS.experimental.configFile": [
+    "./packages/design-system/tailwind.config.ts"
+  ]

설정 파일 경로 자동 확인 스크립트:

문서화 제안: 이전 PR 학습에 따르면 컨벤션 문서는 docs/ 디렉터리에 정리 예정이었습니다. 여기 변경사항(.vscode 설정 의도, 모노레포에서 configFile 지정 이유, Storybook/Chromatic와의 연관성)을 docs/design-system/storybook.md 등으로 간단히 기록하면 온보딩에 도움이 됩니다.


🏁 Script executed:

#!/bin/bash
# 리포지토리 내 tailwind 설정 파일 위치 확인
fd -t f -E node_modules -E dist -E build -E .turbo -g "**/tailwind.config.*" -a | sed 's/^/.\/&/'

Length of output: 154


.vscode/settings.json: Tailwind CSS 설정 파일 경로 수정 필요

실제 리포지토리 내에 Tailwind 설정 파일은 packages/design-system이 아닌 apps/extension/tailwind.config.ts 하나뿐입니다. 따라서 VS Code 확장 기능의 인텔리센스가 올바르게 동작하도록 아래와 같이 설정을 변경해 주세요.

• 파일: .vscode/settings.json

  • 기존
    "tailwindCSS.experimental.configFile": "./packages/design-system/styles.css"
  • 변경 제안
    "editor.quickSuggestions": {
      "strings": true
    },
    - "tailwindCSS.experimental.configFile": "./packages/design-system/styles.css"
    + "tailwindCSS.experimental.configFile": "./apps/extension/tailwind.config.ts"
    }

• (추가) 모노레포에서 다수의 Tailwind 설정 파일을 관리해야 할 경우 배열 형태로 지정할 수 있습니다.

"tailwindCSS.experimental.configFile": [
  "./apps/extension/tailwind.config.ts"
  // 향후 design-system 패키지에 config 파일이 생기면 여기에 추가
]

• 설정 파일 경로 자동 확인 스크립트 예시

# 워크스페이스 내 tailwind.config.* 파일을 상대경로(./…) 형태로 출력
fd -t f \
   -E node_modules -E dist -E build -E .turbo \
   -g "tailwind.config.*" \
   --strip-cwd-prefix | sed 's|^|./|'

문서화: 위 변경사항(.vscode 설정 의도, 다중 config 관리 이유 등)은 docs/ 디렉터리(docs/design-system/storybook.md 등)에 간단히 정리해 두시면 온보딩 및 유지보수에 도움이 됩니다.

🤖 Prompt for AI Agents
.vscode/settings.json around lines 20-21: the Tailwind config path is pointing
to ./packages/design-system/styles.css but the repo only has
apps/extension/tailwind.config.ts; update "tailwindCSS.experimental.configFile"
to reference "./apps/extension/tailwind.config.ts" (or replace the value with an
array containing that path if you want to support multiple configs in the
monorepo), and optionally add a short note in docs/ (e.g.,
docs/design-system/storybook.md) describing the VS Code setting and how to add
additional config paths.

}
32 changes: 32 additions & 0 deletions packages/design-system/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type { StorybookConfig } from '@storybook/react-vite';
import { dirname, join } from 'path';

/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string): string {
return dirname(require.resolve(join(value, 'package.json')));
}
Comment on lines +8 to +10
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

ESM 환경에서 require 미정의 오류 — createRequire 사용으로 교체 필요

design-system 패키지는 ESM("type": "module")입니다. ESM 컨텍스트에서 require는 정의되어 있지 않아 Storybook 실행 시 즉시 크래시합니다. Node의 createRequire로 대체하세요.

아래와 같이 수정 제안드립니다:

 import type { StorybookConfig } from '@storybook/react-vite';
 import { dirname, join } from 'path';
+import { createRequire } from 'node:module';
+
+const require = createRequire(import.meta.url);

 /**
  * This function is used to resolve the absolute path of a package.
  * It is needed in projects that use Yarn PnP or are set up within a monorepo.
  */
 function getAbsolutePath(value: string): string {
   return dirname(require.resolve(join(value, 'package.json')));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
function getAbsolutePath(value: string): string {
return dirname(require.resolve(join(value, 'package.json')));
}
import type { StorybookConfig } from '@storybook/react-vite';
import { dirname, join } from 'path';
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
/**
* This function is used to resolve the absolute path of a package.
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
*/
function getAbsolutePath(value: string): string {
return dirname(require.resolve(join(value, 'package.json')));
}
🤖 Prompt for AI Agents
In packages/design-system/.storybook/main.ts around lines 8 to 10, the function
uses require which crashes in ESM packages; replace require by creating a
require function via Node's createRequire from the 'module' package (import or
require createRequire at top), then use that created require to call
resolve/join so getAbsolutePath works in ESM; ensure the createRequire is
initialized (e.g., createRequire(import.meta.url)) and used instead of raw
require.

const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
getAbsolutePath('@chromatic-com/storybook'),
getAbsolutePath('@storybook/addon-docs'),
getAbsolutePath('@storybook/addon-onboarding'),
getAbsolutePath('@storybook/addon-a11y'),
getAbsolutePath('@storybook/addon-vitest'),
],
framework: {
name: getAbsolutePath('@storybook/react-vite'),
options: {},
},
docs: {
defaultName: 'Documentation',
},
typescript: {
check: true,
reactDocgen: 'react-docgen-typescript',
},
};
export default config;
20 changes: 20 additions & 0 deletions packages/design-system/.storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Preview } from '@storybook/react-vite';
import '../styles.css';

const preview: Preview = {
parameters: {
actions: { argTypesRegex: '^on[A-Z].*' },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주로 저희는 액션 on~으로 컨벤션 맞추면 될까용??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

story 부분 설정하면서 생각이 나서! on prefix 설정을 통일하는 것도 괜찮을 것 같아요.
다만 handle이나 다른 컨벤션도 넓게 사용할 거라면 이 설정은 빼도 될 것 같아요! 어떤 방향성이 좋을까요?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저희 서비스가 어차피 구분할 비슷한 기능들이 많은 것도 아니구 개발 사이즈도 큰 건 아니라, on 범위 정도로도 충분히 다 액션 정의해도 될 것 같아요! handle 키워드를 만약 쓰게 된다해도, onHandleToggle 이런 느낌으로 최대한 on prefix 활용하겠습니당


controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/i,
text: /(title|label|name|placeholder|text)$/i,
},
},
},

tags: ['autodocs'],
};

export default preview;
7 changes: 7 additions & 0 deletions packages/design-system/.storybook/vitest.setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as a11yAddonAnnotations from '@storybook/addon-a11y/preview';
import { setProjectAnnotations } from '@storybook/react-vite';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

setProjectAnnotations import 경로 수정 필요

문서 링크(Portable Stories + Vitest) 기준, setProjectAnnotations@storybook/portable-stories(또는 프리뷰 API)에서 가져오는 것이 맞습니다. @storybook/react-vite에서는 노출되지 않아 타입/런타임 에러가 발생할 수 있습니다.

수정 제안:

-import { setProjectAnnotations } from '@storybook/react-vite';
+import { setProjectAnnotations } from '@storybook/portable-stories';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { setProjectAnnotations } from '@storybook/react-vite';
import { setProjectAnnotations } from '@storybook/portable-stories';
🤖 Prompt for AI Agents
In packages/design-system/.storybook/vitest.setup.ts around line 2, the import
of setProjectAnnotations from '@storybook/react-vite' is incorrect and can cause
type/runtime errors; change the import source to '@storybook/portable-stories'
(or the Storybook preview API package your project uses), update any named
import if necessary, run TS/tsc or vitest typecheck to confirm no remaining
import errors, and adjust any surrounding usage to match the exported signature
from the new module.

import * as projectAnnotations from './preview';

// This is an important step to apply the right configuration when testing your stories.
// More info at: https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest#setprojectannotations
setProjectAnnotations([a11yAddonAnnotations, projectAnnotations]);
21 changes: 20 additions & 1 deletion packages/design-system/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
// For more info, see https://github.com/storybookjs/eslint-plugin-storybook#configuration-flat-config-format
import storybook from 'eslint-plugin-storybook';

import config from '@pinback/eslint-config/react-internal';

/** @type {import("eslint").Linter.Config} */
export default config;
export default [
...storybook.configs['flat/recommended'],
...config,
{
files: ['**/*.js', '**/*.ts'],
ignores: [
Comment on lines +11 to +12
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

파일 글롭 범위 확장 필요(jsx/tsx/mdx 포함)

현재 js/ts만 대상으로 하여 TSX/JSX/MDX 파일에 규칙 오버라이드가 적용되지 않습니다. React/Storybook 환경에서는 TSX/MDX가 핵심이므로 포함이 필요합니다. 특히 이 블록에서 no-undef 등을 끄는 의도가 TSX에도 반영되어야 합니다.

-    files: ['**/*.js', '**/*.ts'],
+    files: ['**/*.{js,jsx,ts,tsx,mdx}'],
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
files: ['**/*.js', '**/*.ts'],
ignores: [
files: ['**/*.{js,jsx,ts,tsx,mdx}'],
ignores: [
🤖 Prompt for AI Agents
In packages/design-system/eslint.config.mjs around lines 11 to 12, the files
globs only include '**/*.js' and '**/*.ts' so ESLint overrides aren't applied to
JSX/TSX/MDX; update the files array to also include '**/*.jsx', '**/*.tsx', and
'**/*.mdx' (and if used, '**/*.mts'/'**/*.cts' variants) so rules like disabling
no-undef are applied to React/Storybook files as well; keep ordering consistent
and ensure any existing overrides referencing ts/js still match the expanded
globs.

'node_modules',
'dist',
'build',
'public',
'public/**',
'public/**/*',
'storybook-static',
'icons/**/*',
],
},
];
22 changes: 19 additions & 3 deletions packages/design-system/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,41 @@
},
"scripts": {
"lint": "eslint .",
"build": "vite build",
"check-types": "tsc --noEmit",
"build": "vite build",
"build:storybook": "storybook build",
"dev:storybook": "storybook dev -p 6006",
"generate:component": "turbo gen react-component"
},
Comment on lines 12 to 19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

CI 실패 원인: pnpm-lock.yaml 스펙 불일치 — 루트에서 재생성 필요

파이프라인 에러 메시지처럼 lockfile이 package.json과 맞지 않습니다. 워크스페이스 루트에서 재생성하세요.

권장 절차:

  • pnpm 버전 고정 확인(루트 .node-version/.tool-versions 혹은 CI와 동일)
  • 루트에서 다음 실행:
pnpm -w install
pnpm -w dedupe
git add pnpm-lock.yaml

필요 시 제가 워크스페이스 범위 점검 스크립트 제공 가능합니다.

Also applies to: 21-22, 39-40

🤖 Prompt for AI Agents
packages/design-system/package.json lines 12-19 (also applies to lines 21-22,
39-40): CI is failing because pnpm-lock.yaml is out of sync with package.json;
fix by regenerating the lockfile from the workspace root using the same pnpm
version as CI. At the repository root confirm/pin pnpm version (via
.node-version/.tool-versions or CI config), run pnpm -w install then pnpm -w
dedupe, verify changes, git add pnpm-lock.yaml and commit; ensure the workspace
root lockfile (not per-package) is updated so package.json and pnpm-lock.yaml
match.

"devDependencies": {
"@chromatic-com/storybook": "4.1.1",
"@pinback/eslint-config": "workspace:*",
"@pinback/tailwind-config": "workspace:*",
"@pinback/typescript-config": "workspace:*",
"@storybook/addon-a11y": "9.1.3",
"@storybook/addon-docs": "9.1.3",
"@storybook/addon-onboarding": "^9.1.3",
"@storybook/addon-vitest": "9.1.3",
"@storybook/blocks": "^8.6.14",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

얘만 다른 의존성과 버전이 다른 이유가 있을까요??

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

따로 설정한 부분 없이 패키지 매니저로 add만했는데 저렇게 설정된 것 같아요!
달라도 크게 문제가 되지는 않을 것 같습니다 :)

"@storybook/react-vite": "9.1.3",
"@tailwindcss/vite": "^4.1.12",
"@vitejs/plugin-react": "^4.5.2",
"@turbo/gen": "^2.5.0",
"@types/node": "^22.15.3",
"@types/react": "19.1.0",
"@types/react-dom": "19.1.1",
"@vitejs/plugin-react": "^4.5.2",
"@vitest/browser": "^3.2.4",
"@vitest/coverage-v8": "^3.2.4",
"chromatic": "^13.1.3",
"eslint": "^9.33.0",
"eslint-plugin-storybook": "9.1.3",
"playwright": "^1.55.0",
"storybook": "9.1.3",
"tailwindcss": "^4.1.12",
"typescript": "5.9.2",
"typescript-eslint": "^8.39.1",
"vite": "^7.1.2"
"vite": "^7.1.2",
"vitest": "^3.2.4"
Comment on lines +36 to +48
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Vite 7과 @vitejs/plugin-react 호환성 확인 필요

현재 Vite ^7.1.2와 plugin-react ^4.5.2 조합입니다. 메이저 호환성에 이슈가 없는지 최신 문서로 확인 부탁드립니다.

검증 스크립트(루트에서 실행):


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo "Vite: $(jq -r '.devDependencies.vite' packages/design-system/package.json)"
echo "Plugin-react: $(jq -r '.devDependencies[\"@vitejs/plugin-react\"]' packages/design-system/package.json)"
echo "참고: 공식 호환성 테이블 확인 권장."

Length of output: 490


다음 스크립트를 실행하여 package.json에 지정된 Vite 및 @vitejs/plugin-react 버전과, 해당 플러그인의 peerDependencies를 함께 확인해 주세요.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# package.json에서 Vite 버전 조회
VITE_VERSION=$(jq -r '.devDependencies.vite // .dependencies.vite' packages/design-system/package.json)
# package.json에서 @vitejs/plugin-react 버전 조회
PLUGIN_RAW=$(jq -r '.devDependencies["@vitejs/plugin-react"] // .dependencies["@vitejs/plugin-react"]' packages/design-system/package.json)

echo "Vite version: $VITE_VERSION"
echo "Plugin React version: $PLUGIN_RAW"

# ^ 또는 ~ 제거
PLUGIN_VERSION=${PLUGIN_RAW#^}
PLUGIN_VERSION=${PLUGIN_VERSION#~}

echo "Fetching peerDependencies for @vitejs/plugin-react@$PLUGIN_VERSION"
curl -s https://registry.npmjs.org/@vitejs/plugin-react/$PLUGIN_VERSION | jq '.peerDependencies'

Length of output: 719


Vite 7.1.2와 @vitejs/plugin-react@4.5.2 호환성 문제 확인
@vitejs/plugin-react@4.5.2의 peerDependencies를 조회한 결과, 지원하는 Vite 범위가 ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0로 명시되어 있어, 정식 출시된 Vite 7.1.2는 포함되지 않습니다.

• 대상 파일

  • packages/design-system/package.json (devDependencies)

• 조치 방안 (필수)

  1. Vite 버전을 안정적인 6.x 대로 하향 조정하거나,
  2. Vite 7 정식 버전을 지원하는 @vitejs/plugin-react의 상위 버전(예: 5.x)으로 업그레이드

위 중 하나를 선택해 의존성 충돌을 해소해 주세요.

🤖 Prompt for AI Agents
In packages/design-system/package.json around lines 36 to 48, the
@vitejs/plugin-react@4.5.2 peerDependencies do not officially include Vite
7.1.2; fix by choosing one: either (A) change the Vite dependency to a stable
6.x version (e.g., ^6.0.0) or (B) upgrade @vitejs/plugin-react to a version that
supports Vite 7 (e.g., ^5.x), then run your package manager to reinstall, update
lockfile, and verify the dev/build/storybook scripts succeed.

},
"dependencies": {
"@radix-ui/react-slot": "^1.2.3",
Expand Down
28 changes: 28 additions & 0 deletions packages/design-system/src/Introduction.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Meta } from '@storybook/blocks';

<Meta title="Introduction" />

# PinBack Design System (pds)

#### pds는 PinBack 서비스를 위한 통합된 디자인 언어입니다.

<br />
<br />
<br />

## pds 사용하기

#### pds는 총 3개의 서비스에 걸쳐 제공됩니다. [(Github)](https://github.com/Pinback-Team/pinback-client)<br />이 사이트는 모든 PinBack 서비스의 기반이 되어 디자인에 필요한 가이드라인 및 스펙을 제공합니다.

- client
- extension
- landing

<br />

## 가이드라인

- Components
- Colors
- Fonts
- Icons
18 changes: 18 additions & 0 deletions packages/design-system/src/components/button/Button.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { Meta, StoryObj } from '@storybook/react-vite';
import Button from './Button';

// Storybook에 컴포넌트를 어떻게 표시할지 정의합니다.
const meta: Meta<typeof Button> = {
title: 'UI/Button',
component: Button,
tags: ['autodocs'],
};

export default meta;
type Story = StoryObj<typeof Button>;

export const Primary: Story = {
args: {
children: 'Primary Button',
},
};
12 changes: 10 additions & 2 deletions packages/design-system/src/components/button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
const Button = () => {
return <div>Button</div>;
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
}
Comment on lines +1 to +3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

타입 네임스페이스 직접 참조 지양: React 타입은 명시적으로 import

현재 파일에서 React 심볼을 타입 위치에서 사용하지만 import가 없습니다. TS 설정에 따라 Cannot find name 'React'가 발생할 수 있습니다. 타입만 import하도록 변경하세요.

-interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
-  children: React.ReactNode;
-}
+import type { ButtonHTMLAttributes, ReactNode } from 'react';
+
+interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
+  children: ReactNode;
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
children: React.ReactNode;
}
import type { ButtonHTMLAttributes, ReactNode } from 'react';
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
children: ReactNode;
}
🤖 Prompt for AI Agents
In packages/design-system/src/components/button/Button.tsx around lines 1 to 3,
the code references the React namespace in type positions without importing it;
add explicit type imports from 'react' and update the interface to use those
types. Specifically, import the types (e.g. import type { ButtonHTMLAttributes,
ReactNode } from 'react'), then change the interface to extend
ButtonHTMLAttributes<HTMLButtonElement> and use ReactNode for children so the
file no longer relies on the global React symbol.


const Button = ({ children, ...props }: ButtonProps) => {
return (
<button type="button" {...props}>
{children}
</button>
);
};

export default Button;
16 changes: 16 additions & 0 deletions packages/design-system/turbo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "../../node_modules/turbo/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"with": ["build:storybook"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

찾아보니, 스토리북 CLI는 디렉토리 기준으로 main.tz, tsconfig 등을 읽어야 하는데 이게 디자인시스템 내로 들어가있어서 루트딴에서 실행이 안되는군여

이렇게 설정하면 확실히 경로이동 덜 번거로워질 것 같네요! 감사합니다

},
Comment on lines +5 to +7
Copy link

@coderabbitai coderabbitai bot Aug 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

"with"는 Turbo 설정 키가 아닙니다 — "dependsOn"으로 교체하세요

Turbo 설정에서 task 간 의존성을 선언하려면 "dependsOn"를 사용해야 합니다. 현재 "with"는 인식되지 않아 build 시 storybook 빌드가 실행되지 않습니다.

아래처럼 수정하면 루트의 기본 빌드 의존성("^build")도 유지하면서 이 패키지의 build가 build:storybook을 선행 실행하도록 보장할 수 있습니다.

-    "build": {
-      "with": ["build:storybook"]
-    },
+    "build": {
+      "dependsOn": ["^build", "build:storybook"]
+    },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"build": {
"with": ["build:storybook"]
},
"build": {
"dependsOn": ["^build", "build:storybook"]
},
🤖 Prompt for AI Agents
In packages/design-system/turbo.json around lines 5 to 7, the task configuration
uses the invalid key "with" instead of Turborepo's "dependsOn", so storybook
isn't being run as a dependency; replace the "with" key with "dependsOn" and set
its value to include the existing root dependency specifier (e.g. "^build") plus
"build:storybook" so this package's build will run build:storybook first while
preserving the root-level build dependency.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with도 정식 옵션이 맞지마 두개 차이점이 좀 있는거같아요. with는 동시실행이 목적이고 dependsOn은 빌드 순서 보장이 필요할 때 사용하는것같아요. 확인해보고 우리 프로젝트에 필요한거 적용하면 좋을것같네요-!!

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧩 Analysis chain

🌐 Web query:

Turborepo task configuration "with" vs "dependsOn" official documentation latest version

💡 Result:

Short answer — purpose and difference

  • dependsOn: declares task ordering/requirements — tasks that must complete before this task runs (supports same-package names, package-scoped names, and the ^ microsyntax to depend on tasks in package dependencies). (turborepo.com, turbo.build)
  • with: runs one or more tasks alongside a (usually long-running/persistent) task; it does NOT create a “wait-for-complete” dependency — it ensures the named task(s) are started whenever the primary task runs (used for dev servers, sidecars). (turborepo.com, turbo.build)

Key details / how to choose

  • Use dependsOn when you need deterministic ordering (e.g., build library before app). The ^ prefix means “run the task for my dependency packages first.” Example: "dependsOn": ["^build"]. (turborepo.com, turbo.build)
  • Use with when one task is long-running (persistent) and you want another task started alongside it (for example, start api#dev when web#dev runs). Long-running/persistent tasks can’t be used as completion dependencies — they don’t exit — so dependsOn is unsuitable for them. Example: "with": ["api#dev"] with "persistent": true. (turborepo.com, turbo.build)
  • dependsOn affects the task graph and caching semantics (it ensures upstream tasks complete so outputs are available). with is about simultaneous execution at runtime and does not imply the other task must finish. (turborepo.com, turbo.build)

Examples (from the official docs)

  • dependsOn (build order):
    {
    "tasks": {
    "build": { "dependsOn": ["^build"] }
    }
    }
    (turborepo.com)

  • with (dev sidecar):
    {
    "tasks": {
    "dev": {
    "with": ["api#dev"],
    "persistent": true,
    "cache": false
    }
    }
    }
    (turborepo.com)

Notes about schema and naming

  • Official docs you’ll see examples using the "tasks" object in turbo.json (the main Turborepo docs). Some mirrors/variants or schema examples use "pipeline" (older/newer schema differences or mirrors may show that). If you’re updating or authoring turbo.json, use the shape recommended by the version of Turborepo you run (the docs pages above are the canonical reference). (turborepo.com, turbo.hector.im)

I pulled these details from the official Turborepo docs today (I checked the docs on August 21, 2025). If you want:

  • Direct links to the exact doc pages I used, or
  • A small turbo.json example tailored to your repo (apps/packages names), or
  • A short checklist for converting an existing setup to use with vs dependsOn —

tell me which and I’ll fetch or generate it.

Citations:


@jjangminii 맞습니다! 제가 잘못된 정보를 제공했네요. 죄송합니다.

"with"와 "dependsOn" 모두 정식 Turbo 옵션입니다:

  • dependsOn: 순차 실행 (의존성 작업이 완료된 후 현재 작업 실행)
  • with: 병렬 실행 (주로 persistent/long-running 작업과 함께 사용)

현재 상황에서는 Storybook 빌드가 완료된 후 메인 빌드가 실행되어야 한다면 dependsOn이 더 적절할 것 같습니다:

"build": {
  "dependsOn": ["^build", "build:storybook"]
}

하지만 만약 병렬 실행이 목적이라면 현재 with 설정도 유효합니다. 프로젝트의 빌드 플로우에 따라 선택하시면 됩니다!

정확한 정보 수정해 주셔서 감사합니다. 🙏


✏️ Learnings added
Learnt from: jjangminii
PR: Pinback-Team/pinback-client#14
File: packages/design-system/turbo.json:5-7
Timestamp: 2025-08-21T08:07:11.386Z
Learning: Turborepo task configuration supports both "with" and "dependsOn" keys: "dependsOn" is for sequential task execution where dependencies must complete first, while "with" is for concurrent execution alongside persistent/long-running tasks.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

"build:storybook": {
"outputs": ["storybook-static/**"]
},
"dev:storybook": {
"cache": false,
"persistent": true
}
}
}
36 changes: 36 additions & 0 deletions packages/design-system/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
/// <reference types="vitest/config" />
import tailwindcss from '@tailwindcss/vite';
import react from '@vitejs/plugin-react';
import path from 'path';
import { defineConfig } from 'vite';
import { fileURLToPath } from 'node:url';
import { storybookTest } from '@storybook/addon-vitest/vitest-plugin';
const dirname =
typeof __dirname !== 'undefined'
? __dirname
: path.dirname(fileURLToPath(import.meta.url));

// More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
Expand All @@ -27,4 +35,32 @@ export default defineConfig({
},
},
},
test: {
projects: [
{
extends: true,
plugins: [
// The plugin will run tests for the stories defined in your Storybook config
// See options at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon#storybooktest
storybookTest({
configDir: path.join(dirname, '.storybook'),
}),
],
test: {
name: 'storybook',
browser: {
enabled: true,
headless: true,
provider: 'playwright',
instances: [
{
browser: 'chromium',
},
],
},
setupFiles: ['.storybook/vitest.setup.ts'],
},
},
],
},
});
1 change: 1 addition & 0 deletions packages/design-system/vitest.shims.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="@vitest/browser/providers/playwright" />
Loading
Loading