-
Notifications
You must be signed in to change notification settings - Fork 1
Setting(project): svg sprite 설정 #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
ab3e06d
93cad1e
44823ce
2d65fb1
4b9d15a
138fd20
245fadb
9200f56
c9a92b7
1e218ed
b15d633
ddc1910
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,10 @@ | |
| "build": "vite build", | ||
| "build:storybook": "storybook build", | ||
| "dev:storybook": "storybook dev -p 6006", | ||
| "generate:component": "turbo gen react-component" | ||
| "icons:clean": "svgo -f src/icons/source --config=./svgo.config.mjs --multipass", | ||
| "generate:icons": "tsx src/icons/scripts/generate-icon-list.ts && prettier --write src/icons/iconNames.ts", | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저번에 문제 생긴 prettier 부분을 이렇게 해결해주셨네요 👍 |
||
| "generate:component": "turbo gen react-component", | ||
| "icons": "pnpm icons:clean && pnpm generate:icons" | ||
| }, | ||
| "devDependencies": { | ||
| "@chromatic-com/storybook": "4.1.1", | ||
|
|
@@ -42,18 +45,21 @@ | |
| "playwright": "^1.55.0", | ||
| "storybook": "9.1.3", | ||
| "tailwindcss": "^4.1.12", | ||
| "tsx": "^4.20.4", | ||
| "typescript": "5.9.2", | ||
| "typescript-eslint": "^8.39.1", | ||
| "vite": "^7.1.2", | ||
| "vitest": "^3.2.4" | ||
| }, | ||
| "dependencies": { | ||
| "@pivanov/vite-plugin-svg-sprite": "^3.1.3", | ||
| "@radix-ui/react-slot": "^1.2.3", | ||
| "class-variance-authority": "^0.7.1", | ||
| "clsx": "^2.1.1", | ||
| "lucide-react": "^0.540.0", | ||
| "react": "^19.1.0", | ||
| "react-dom": "^19.1.0", | ||
| "svgo": "^4.0.0", | ||
| "tailwind-merge": "^3.3.1", | ||
| "tw-animate-css": "^1.3.7" | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import type { IconName } from '../iconNames'; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. React 네임스페이스 타입 직접 사용으로 인한 TS 빌드 오류 가능성
-import type { IconName } from '../iconNames';
+import type { IconName } from '../iconNames';
+import type { SVGProps } from 'react';
...
-interface IconProps extends React.SVGProps<SVGSVGElement> {
+interface IconProps extends SVGProps<SVGSVGElement> {Also applies to: 30-39 🤖 Prompt for AI Agents |
||
| import React from 'react'; | ||
| import clsx from 'clsx'; | ||
|
|
||
| type IconRotate = 90 | 180 | 270; | ||
|
|
||
| type IconColor = | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 와우..고생하셨습니다! |
||
| | 'main0' | ||
| | 'main100' | ||
| | 'main200' | ||
| | 'main300' | ||
| | 'main400' | ||
| | 'main500' | ||
| | 'main600' | ||
| | 'gradient-start' | ||
| | 'gradient-end' | ||
| | 'secondary' | ||
| | 'gray0' | ||
| | 'gray100' | ||
| | 'gray200' | ||
| | 'gray300' | ||
| | 'gray400' | ||
| | 'gray500' | ||
| | 'gray600' | ||
| | 'gray700' | ||
| | 'gray800' | ||
| | 'gray900' | ||
| | 'white-bg' | ||
| | 'gray-bg' | ||
| | 'font-black-1' | ||
| | 'font-gray-2' | ||
| | 'font-gray-3' | ||
| | 'font-ltgray-4' | ||
| | 'font-ltgray-5' | ||
| | 'error' | ||
| | 'success' | ||
| | 'category-red-text' | ||
| | 'category-purple-text' | ||
| | 'category-navyblue-text' | ||
| | 'category-skyblue-text' | ||
| | 'category-emerald-text' | ||
| | 'category-navygreen-text' | ||
| | 'category-khaki-text' | ||
| | 'category-orange-text' | ||
| | 'category-amber-text' | ||
| | 'category-maroon-text' | ||
| | 'category-red-bg' | ||
| | 'category-purple-bg' | ||
| | 'category-navyblue-bg' | ||
| | 'category-skyblue-bg' | ||
| | 'category-emerald-bg' | ||
| | 'category-navygreen-bg' | ||
| | 'category-khaki-bg' | ||
| | 'category-orange-bg' | ||
| | 'category-amber-bg' | ||
| | 'category-maroon-bg'; | ||
|
|
||
| interface IconProps extends React.SVGProps<SVGSVGElement> { | ||
| name: IconName; | ||
| size?: number | string; | ||
| width?: number | string; | ||
| height?: number | string; | ||
| color?: IconColor; | ||
| className?: string; | ||
| rotate?: IconRotate; | ||
| ariaHidden?: boolean; | ||
| } | ||
|
|
||
| export const Icon = ({ | ||
| name, | ||
| size, | ||
| width, | ||
| height, | ||
| color, | ||
| className, | ||
| rotate, | ||
| ariaHidden = true, | ||
| ...rest | ||
| }: IconProps) => { | ||
| const w = width ?? size ?? 20; | ||
| const h = height ?? size ?? 20; | ||
|
Comment on lines
+80
to
+81
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fallback까지 굳굳 👍 |
||
|
|
||
| const rotateClass = | ||
| rotate === 90 | ||
| ? 'rotate-90' | ||
| : rotate === 180 | ||
| ? 'rotate-180' | ||
| : rotate === 270 | ||
| ? 'rotate-[270deg]' | ||
| : ''; | ||
|
|
||
| const combined = clsx('inline-block', rotateClass, className); | ||
|
|
||
| return ( | ||
| <svg | ||
| width={typeof w === 'number' ? `${w}px` : w} | ||
| height={typeof h === 'number' ? `${h}px` : h} | ||
| className={combined} | ||
| style={color ? { color: `var(--color-${color})` } : undefined} | ||
| aria-hidden={ariaHidden} | ||
| {...rest} | ||
| > | ||
| <use href={`#icon-${name}`} /> | ||
| </svg> | ||
|
Comment on lines
+103
to
+104
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain스프라이트 주입 책임 위치 확인: 소비 앱에서 심볼 미주입 시 렌더 실패
권장 옵션:
다음 스크립트로 현재 리포에서 플러그인 적용 위치를 점검해 주세요. 🏁 Script executed: #!/bin/bash
set -euo pipefail
echo "== vite.config.ts 내 svg-sprite 플러그인 사용 위치 검색 =="
fd -t f vite.config.ts | while read -r f; do
echo "--- $f ---"
rg -nP "@pivanov/vite-plugin-svg-sprite|svgSpritePlugin" -n -C2 "$f" || true
doneLength of output: 1259 스프라이트 주입 위치 검토 필요 검토 결과, SVG 스프라이트 플러그인은 영향 받는 파일:
권장 조치:
🤖 Prompt for AI Agents |
||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| // 이 파일은 자동 생성 파일입니다. (직접 수정 금지) | ||
| export const iconNames = [ | ||
| 'ic_arrow_down_active', | ||
| 'ic_arrow_down_disable', | ||
| 'ic_bookmark_active', | ||
| 'ic_bookmark_disable', | ||
| 'ic_clock_active', | ||
| 'ic_clock_disable', | ||
| 'ic_close', | ||
| 'ic_details_category', | ||
| 'ic_details_disable', | ||
| 'ic_info', | ||
| 'ic_plus', | ||
| ] as const; | ||
| export type IconName = (typeof iconNames)[number]; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| export { Icon } from './components/icon'; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import { readdirSync, writeFileSync } from 'fs'; | ||
| import { basename, dirname, join } from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
|
|
||
| const __filename = fileURLToPath(import.meta.url); | ||
| const __dirname = dirname(__filename); | ||
|
|
||
| const ICON_DIR = join(__dirname, '../source'); | ||
| const OUTPUT_PATH = join(__dirname, '../iconNames.ts'); | ||
|
|
||
| const files = readdirSync(ICON_DIR).filter((file) => file.endsWith('.svg')); | ||
|
|
||
| const iconNames = files.map((file) => basename(file, '.svg')); | ||
|
|
||
| const content = `// 이 파일은 자동 생성 파일입니다. (직접 수정 금지) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 generate빌드하면 그때 그 자동 생성되는 구간이였나용??
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. generate빌드하면 이 파일의 함수들로 iconsName파일에 자동생성됩니당 |
||
| export const iconNames = ${JSON.stringify(iconNames)} as const; | ||
| export type IconName = typeof iconNames[number]; | ||
| `; | ||
|
|
||
| writeFileSync(OUTPUT_PATH, content); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| export default { | ||
| multipass: true, | ||
| plugins: [ | ||
| // 기본 최적화 + viewBox 유지 | ||
| { name: 'preset-default', params: { overrides: { removeViewBox: false } } }, | ||
| // 루트 <svg>의 width/height 제거 | ||
| { name: 'removeDimensions' }, | ||
| ], | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| import svgSpritePlugin from '@pivanov/vite-plugin-svg-sprite'; | ||
| /// <reference types="vitest/config" /> | ||
| import tailwindcss from '@tailwindcss/vite'; | ||
| import react from '@vitejs/plugin-react'; | ||
|
|
@@ -12,7 +13,15 @@ const dirname = | |
|
|
||
| // More info at: https://storybook.js.org/docs/next/writing-tests/integrations/vitest-addon | ||
| export default defineConfig({ | ||
| plugins: [react(), tailwindcss()], | ||
| plugins: [ | ||
| react(), | ||
| tailwindcss(), | ||
| svgSpritePlugin({ | ||
| iconDirs: ['src/icons/source'], | ||
| symbolId: 'icon-[name]', | ||
| inject: 'body-last', | ||
| }), | ||
| ], | ||
|
Comment on lines
+16
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chain라이브러리 내부에서 스프라이트를 주입하면 소비 애플리케이션에서는 주입이 이뤄지지 않을 수 있습니다 현재 플러그인은 design-system 패키지의 Vite 설정에만 추가되어 있습니다. 이 설정은 라이브러리 빌드에는 영향을 주지만, 이 라이브러리를 사용하는 실제 앱(소비자)의 HTML에는 스프라이트가 자동 주입되지 않습니다. 결과적으로 소비 앱에서 대안:
지금 상태는 소비 앱 관점에서 “심볼 미주입” 위험이 높으므로 보완이 필요합니다. 원하시면 소비 앱용 Provider 컴포넌트/가이드를 함께 제안드리겠습니다. 소비 앱 쪽에 동일 플러그인이 설정되어 있는지 확인: 🏁 Script executed: #!/bin/bash
# 레포 전체에서 해당 플러그인 사용 여부 확인
rg -n -C2 -P "@pivanov/vite-plugin-svg-sprite|svgSpritePlugin\\("Length of output: 2563 소비 애플리케이션 Vite 설정에 SVG 스프라이트 플러그인 미적용 – 심볼 주입 누락 위험 현재 조치 방안:
필요 시 소비 앱용 Provider 컴포넌트 및 가이드 작성도 지원 가능합니다. 🤖 Prompt for AI Agents
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분 체크해보셔야 할 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain@constantly-dev 좋은 지적이에요! 이 부분 확실히 체크해봐야겠습니다. SVG 스프라이트 설정이 디자인 시스템에만 있으면 실제 앱에서 아이콘이 안 보일 수 있거든요. 🏁 Script executed: Length of output: 1136 🏁 Script executed: Length of output: 2550 예상했던 대로 문제가 있네요! 🚨 현재 상황 분석
문제점현재 설정으로는 아이콘이 표시되지 않습니다:
해결 방안각 앱의 1.
|
||
| resolve: { | ||
| alias: { | ||
| '@': path.resolve(__dirname, 'src'), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
아이콘 스크립트 체인 및 Prettier 의존성 확인 필요
icons:clean과generate:icons를 함께 실행하는 편의 스크립트(예:icons)를 추가하면 DX가 좋아집니다.generate:icons에서prettier --write를 호출하는데, 이 패키지(또는 워크스페이스 루트)에 Prettier가 설치되어 있어야 합니다. 현재 이 패키지의 devDependencies에는 Prettier가 보이지 않습니다.확인을 위해 다음 스크립트를 실행해 주세요. 목적: (1) 이 리포 내 Prettier 설치 여부, (2) svgo 설정 파일 존재 여부, (3) 아이콘 리스트 스크립트 존재 여부.
추가 제안(선택):
"scripts": { ... - "icons:clean": "svgo -f src/icons/source --config=./svgo.config.mjs --multipass", - "generate:icons": "tsx src/icons/scripts/generate-icon-list.ts && prettier --write src/icons/iconNames.ts", + "icons:clean": "svgo -f src/icons/source --config=./svgo.config.mjs --multipass", + "generate:icons": "tsx src/icons/scripts/generate-icon-list.ts && prettier --write src/icons/iconNames.ts", + "icons": "pnpm icons:clean && pnpm generate:icons", ... }🏁 Script executed:
Length of output: 590
디자인 시스템 패키지에 Prettier 설치 및 아이콘 스크립트 통합 필요
검증 결과:
generate:icons실행 시prettier명령을 찾지 못해 실패함packages/design-system/svgo.config.mjs존재packages/design-system/src/icons/scripts/generate-icon-list.ts존재해결 방안:
packages/design-system의devDependencies에 Prettier 추가 또는 워크스페이스 루트에 Prettier 설치예시 변경:
"scripts": { … "icons:clean": "svgo -f src/icons/source --config=./svgo.config.mjs --multipass", "generate:icons": "tsx src/icons/scripts/generate-icon-list.ts && prettier --write src/icons/iconNames.ts", + "icons": "pnpm icons:clean && pnpm generate:icons", … }📝 Committable suggestion
🤖 Prompt for AI Agents