2025. 10. 26. 21:57ใTrouble Shooting & Issues/Linkiving

๋ชฉ์ฐจ
1. ์์ด์ฝ ์ปดํฌ๋ํธ, next/image๋ฅผ ์์ด๋ค๊ณ ?
2. @svgr/webpack
3. ์ปดํฌ๋ํธ ์์ฑ ๊ณผ์
4. storybook ์๋ฌ
5. ๊ฒฐ๊ณผ๋ฌผ
1. ์์ด์ฝ ์ปดํฌ๋ํธ, next/image๋ฅผ ์์ด๋ค๊ณ ?
ํ๋ก์ ํธ์๋ IconButton ์ปดํฌ๋ํธ์ ์ฌ์ฉํ๊ธฐ ์ํ ์์ ์ปดํฌ๋ํธ์ธ, CustomImage ์ปดํฌ๋ํธ๊ฐ ์์๋ค.
import NextImage from 'next/image';
import type { ReactElement } from 'react';
type ImageProps = {
src: string;
alt?: string;
width?: number;
height?: number;
};
/**
* ํ
์คํธ์ฉ Image ์ปดํฌ๋ํธ
* - src๋ ํ์
* - alt ๊ธฐ๋ณธ๊ฐ์ ๋น ๋ฌธ์์ด
*/
export default function CustomImage({
src,
alt = '',
width = 20,
height = 20,
...rest
}: ImageProps): ReactElement {
return <NextImage src={src} alt={alt} width={width} height={height} {...rest} />;
next/image๋ฅผ ์ฌ์ฉํ๋ ์ปดํฌ๋ํธ์ด๋ค.
๊ทธ๋ฐ๋ฐ svg, gif, apng ํ์์ Next.js์์ ์ด๋ฏธ์ง ์ต์ ํ๋ฅผ ์งํํด์ฃผ์ง ์๋๋ค๊ณ ํ๋ค.
์ฉ๋์ด ๋งค์ฐ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ฅ ์ฌ์ฉํด๋ ๋๋ค๊ณ ..
๊ทธ๋์ ๋ณดํต ์์ด์ฝ์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง ์ฐพ์๋ณด๋๊น Next์์๋ @svgr/webpack์ด๋ผ๋ ์นํฉ ๋ก๋๋ฅผ ์ค์นํด์ ์ฌ์ฉํ๋ค๊ณ ํ๋ค.
์์ด์ฝ์ ๋ ์ฌ๊ธฐ์ ๊ธฐ์ ์ฌ์ฉํ๊ธฐ ์ ์ ํ๋ค๋ฅ ์์ ์ ํด๋ณด๊ธฐ๋ก ํ๋ค.
2. @svgr/webpack
1. svg ํ์ผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ค : ์ผ๋ฐ / ๋ฆฌ์กํธ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ / ์นํฉ ๋ก๋
svg ํ์ผ์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ธ ๊ฐ์ง๊ฐ ์๋ค.
๊ทธ๋ฅ svg ํ์ผ์ ๋ฐ๋ก ๋ถ๋ฌ์ค๋ ๋ฐฉ๋ฒ, ๋ฆฌ์กํธ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ๋ฅผ ๋ถ์ด๋ ๋ฐฉ๋ฒ, ์นํฉ ๋ก๋๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
| ์ฌ์ฉ ๋ฐฉ๋ฒ | TS/React ์ธ์ | props ์ง์ | |
| ๊ธฐ๋ณธ svg | import MyIcon from './icon.svg'; <img src={MyIcon} /> |
๊ทธ๋ฅ ๋ชจ๋ ๊ฐ์ฒด(string, any type) | ๋ถ๊ฐ |
| ?react ๋ถ์ | import MyIcon from './icon.svg?react'; <MyIcon width={24} height={24} /> |
React ์ปดํฌ๋ํธ | ๊ฐ๋ฅ |
| svgr/webpack | import MyIcon from './icon.svg'; <MyIcon width={24} height={24} /> |
React ์ปดํฌ๋ํธ | ๊ฐ๋ฅ |
React ์ปดํฌ๋ํธ๋ก ๋ณํํ์ฌ ์ฌ์ฉํ๋ฉด svg ํ์ผ์ ํฌ๊ธฐ, ์์ ๋ฑ์ ๋ ํธํ๊ฒ ์กฐ์ํ ์ ์๋ค.
์ฌ๊ธฐ์ ?react ํ๋ผ๋ฏธํฐ๋ฅผ ๋ถ์ด๋ฉด ์ฝ๊ฒ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ณํํ ์ ์์ผ๋, svgr/webpack์ ์ฌ์ฉํ๋ฉด ์ด๊ธฐ ์ธํ ์ด ์ข ํ์ํ๋ค.
?react์ ์ฅ๋จ์ ๊ณผ svgr/webpack์ ์ฅ๋จ์ ์ ๋น๊ตํด๋ณด์.
?react vs svgr/webpack
| ?react | svgr/webpack | |
| ๐ ์ฅ์ | - ํ์ํ SVG๋ง React ์ปดํฌ๋ํธ๋ก ๋ณํ ๊ฐ๋ฅ - Next.js/Turbopack ํ๊ฒฝ์์ ์ค์ ์ด ๊ฐ๋จ - props ์ ๋ฌ ๊ฐ๋ฅ |
- ๋ชจ๋ svg ํ์ผ์ ์๋์ผ๋ก React ์ปดํฌ๋ํธ๋ก ๋ณํ - import ๊ตฌ๋ฌธ๋ง ์จ๋ ๋ฐ๋ก <Icon /> ๊ฐ์ด ์ฌ์ฉ ๊ฐ๋ฅ - props๋ฅผ ํต์ผ๋ ๋ฐฉ์์ผ๋ก ๊ด๋ฆฌ ๊ฐ๋ฅ |
| ๐ ๋จ์ | - import๋ง๋ค ์ผ์ผ์ด ?react ๋ถ์ฌ์ผ ํจ - ํ๋ก์ ํธ ์ ๋ฐ์ ๊ฑธ์ณ ์ผ๊ด๋ ๊ท์น์ ์ ์ฉํ๊ธฐ ์ด๋ ค์ - ๊ธฐ์กด import ๋ฐฉ์๊ณผ ์์ผ ์ํ์ด ์์ |
- ์ด๊ธฐ Webpack/Turbopack ์ค์ ํ์ - ํ์์๋ SVG๊น์ง ๋ชจ๋ React ์ปดํฌ๋ํธ๋ก ๋ณํ๋ ์ ์์ |
์ฅ๋จ์ ์ ๋น๊ตํด๋ณด๋ฉด svgr/webpack์ ์ฌ์ฉํจ์ผ๋ก์จ ์ผ๊ด์ฑ์ ์ป์ ์ ์๋ค๋ ๊ฒ์ ์ ์ ์๋ค.
๋ํ svgr ์ฌ์ดํธ๋ฅผ ํ์ธํด๋ณด๋ฉด React ์ปดํฌ๋ํธ๋ก ๋ณํํ๊ณ ์ถ์ง ์์ svg ํ์ผ์ ๋ฐ๋ก ์ง์ ํ ์๊ฐ ์๋ค๊ณ ํ๋ค.
์ด ํ๋ก์ ํธ๋ ๊ท๋ชจ๊ฐ ๊ฝค ์์ผ๋ฉฐ, ๋ด๊ฐ ์ฐพ์๋ณด๋ฉด์ ์ ์ฉํ๊ณ ์ถ์ ๊ฒ๋ค์ด ์์๊ธฐ ๋๋ฌธ์ svgr/webpack์ ์ฌ์ฉํด๋ณด๊ธฐ๋ก ํ๋ค.
2. svg/webpack ์ค์น ๋ฐ ์ธํ
svgr/webpack์ SVG๋ฅผ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ฐ๊ฟ์ฃผ๋ ํด(์นํฉ ๋ก๋)์ด๋ค.
https://react-svgr.com/docs/what-is-svgr/
SVGR - Transforms SVG into React Components. - SVGR
Transforms SVG into React Components.
react-svgr.com
1. ์ค์นํ๊ธฐ
cli์ ์ ๋ ฅํด์ ๊ฐ๋จํ๊ฒ ์ค์นํด์ค๋ค.
npm install --save-dev @svgr/webpack
# yarn
yarn add --dev @svgr/webpack
2. next.config.js ์ธํ ( turbopack ์ฌ์ฉ ์ )
๊ณตํ์์๋ webpack setting์ ์๋ ค์ฃผ๋๋ฐ, turbopack์ ์ฌ์ฉํ๋ค๋ฉด ๊ทธ๊ฑฐ ์๋ฌ๋๋ค.
์๋ ๋ด์ฉ๋ง ์์ฑํด์ฃผ๋ฉด ๋๋ค.
import type { NextConfig } from 'next';
const nextConfig: NextConfig = {
// svg in turbopack setting
turbopack: {
rules: {
'*.svg': {
loaders: ['@svgr/webpack'],
as: '*.js',
},
},
},
};
export default nextConfig;
3. svgr.d.ts & tsconfig.json ์ธํ ( TypeScript ์ฌ์ฉ ์ )
TypeScript๋ ๋ชจ๋์ ๊ฐ์ ธ์ฌ ๋ ํ์ ์ ์์์ผ ํ๋๋ฐ svg ํ์ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ ์ ๋ณด๊ฐ ์๋ค.
๋ฐ๋ผ์ svgr.d.ts์ svg ํ์ผ์ ํ์ ์ ์ ์ํด์ผ ํ๋ค.
// svgr.d.ts
declare module '*.svg' { // .svg ํ์ฅ์๋ฅผ ๊ฐ์ง ๋ชจ๋ ํ์ผ์ ์ด ๋ชจ๋ ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง์ ์ ์ธ
import React from 'react'; // ์ด ๋ชจ๋์ ํ์
์ React์ ํ์
// React.FC.. : ๋ฐํ๊ฐ์ด ์๊ณ children์ ๋ฐ์ง ์๋ React ์ปดํฌ๋ํธ
// React.SVG.. : ์ด ์ปดํฌ๋ํธ๊ฐ ๋ฐ์ ์ ์๋ props ํ์
(SVG ๊ธฐ๋ณธ ์์ฑ์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์)
const SVG: React.FC<React.SVGProps<SVGSVGElement>>;
export default SVG;
}
svgr.d.ts ๊ฐ์ ๋ชจ๋ ์ ์ธ ํ์ผ์ TypeScript๊ฐ ํ๋ก์ ํธ๋ฅผ ์ปดํ์ผํ ๋ ๊ฐ์ฅ ๋จผ์ ์ฐธ์กฐํด์ผํ๋ค. ๋ฐ๋ผ์ svgr.d.ts๋ฅผ ๊ฐ์ฅ ๋จผ์ include ํ๋๋ก tsconfig.json์ ์์ฑํ๋ค.
// tsconfig.json
...
"include": ["svgr.d.ts", "next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
4. .storybook/main.ts ์ธํ ( storybook ์ฌ์ฉ ์ )
์ด๊ฑด ๋ค์ ์์ฑ
3. ์ปดํฌ๋ํธ ์์ฑ ๊ณผ์
ํ์ํ ํ์ผ๋ค์ ๋ชจ๋ ์์ฑํ์ผ๋ ์ด์ SVG ์ปดํฌ๋ํธ๋ฅผ ๋ ์ฝ๊ฒ ์ฌ์ฉํ๋๋ก ์ธํ ํ ๊ฑฐ๋ค.
์ด ์ํ๋ก SVG ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฐ ๋ฐฉ์์ด ๋ ๊ฒ์ด๋ค.
import MyIcon from './MyIcon.svg';
...
<MyIcon className="..." width={24} height={24} />
์ง๊ธ๋ ์ถฉ๋ถํ ์ฌ์ฉํ๊ธฐ์ ์ข์ง๋ง ์ปดํฌ๋ํธํ ํ์ฌ ์์ฑ์ ์ข ๋ ์ผ๊ด์ฑ์๊ฒ, ์์ ๋กญ๊ฒ ๋ค๋ฃฐ ์ ์๋ค.
1. svg ํ์ผ๋ค ์์
์ฐ์ svg ํ์ผ์ ๊ณ ์ ๊ฐ์ด ๋ค์ด๊ฐ์๋ width, height, fill ์ ๋ชจ๋ current๋ก ๋ฐ๊ฟ์ฃผ์ด์ผ ๋ง์๋๋ก ์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.7071 14.2929C12.3166 14.6834 11.6834 14.6834 11.2929 14.2929L8.70711 11.7071C8.07714 11.0771 8.52331 10 9.41421 10H14.5858C15.4767 10 15.9229 11.0771 15.2929 11.7071L12.7071 14.2929Z" fill="black"/>
</svg>
<svg width="current" height="current" viewBox="0 0 24 24" fill="current" xmlns="http://www.w3.org/2000/svg">
<path d="M12.7071 14.2929C12.3166 14.6834 11.6834 14.6834 11.2929 14.2929L8.70711 11.7071C8.07714 11.0771 8.52331 10 9.41421 10H14.5858C15.4767 10 15.9229 11.0771 15.2929 11.7071L12.7071 14.2929Z" fill="current"/>
</svg>
2. icons.ts ์์ฑ : ์ปดํฌ๋ํธ import
์ค์ SVG ์ปดํฌ๋ํธ๋ฅผ importํ๊ณ , ํ์ ํํ๋ icons.ts๋ฅผ ์์ฑํด์ค๋ค.
// SVG ์์ด์ฝ import
import IC_AllLink from './svgs/all_link.svg';
import IC_ArrowdropDown from './svgs/arrowdrop_down.svg';
import IC_ArrowdropLeft from './svgs/arrowdrop_left.svg';
// ์ปดํฌ๋ํธ๋ค๋ก IconMap ๊ตฌ์ฑ
export const IconMap = {
IC_AllLink,
IC_ArrowdropDown,
IC_ArrowdropLeft,
} as const;
// IconMapTypes = 'IC_Alllink' | 'IC_ArrowdropDown' | 'IC_ArrowdropLeft' | ...
export type IconMapTypes = keyof typeof IconMap;
// ์ฌ์ด์ฆ ๊ตฌ์ฑ
export const IconSizes = {
sm: 16,
md: 20,
lg: 24,
};
// IconSizeTypes = 'sm' | 'md' | 'lg' | ...
export type IconSizeTypes = keyof typeof IconSizes;
3. SVGIcon.tsx ์์ฑ : ์ค์ฌ์ฉํ ์ปดํฌ๋ํธ
์ด ์ปดํฌ๋ํธ๋ฅผ ์ค์ ์์ด์ฝ์ด ํ์ํ ๊ณณ์์ ์ฌ์ฉํ ๊ฑฐ๋ค.
import React from 'react';
import { IconMap, IconMapTypes, IconSizeTypes, IconSizes } from './icons';
// icons.ts์์ ์ ์ํ IconMapTypes, IconSizeTypes๋ฅผ ๊ฐ๊ฐ icon, size์ ํ์
์ผ๋ก ์ ์
export interface SVGIconProps {
icon: IconMapTypes;
size?: IconSizeTypes;
className?: string;
}
const SVGIcon: React.FC<SVGIconProps> = ({ icon, size = 'lg', className }: SVGIconProps) => {
// <SVGIcon icon={'IC_ALLlink'} -> Icon = IconMap[IC_Alllink]
const Icon = IconMap[icon as IconMapTypes];
if (!Icon) return null;
return <Icon className={className} width={IconSizes[size]} height={IconSizes[size]} />;
};
export default SVGIcon;
4. storybook ์๋ฌ
์คํ ๋ฆฌ๋ถ์ด ์ํํด๋ณด๊ธฐ ๊ฐ๋จํ๋๊น ์คํ ๋ฆฌ๋ถ์์ ๋จผ์ ์ํํด๋ดค๋๋ฐ ์๋ฌด๋ฆฌ ์ด๊ฒ์ ๊ฒ ์์ ํด๋ ๊ณ์ ์๋ฌ๊ฐ ๋จ๋ ๊ฒ์ด์๋ค.

๊ทธ๋ฌ๋ค๊ฐ SVGIcon๋ง ์ฌ์ฉํด๋ณด๊ณ , IconButton์ ์ฌ์ฉํด๋ณด๋๊น ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋ ๊ฒ์ ๋ณด๊ณ '์ ๋ ์คํ ๋ฆฌ๋ถ์ด๊ตฌ๋..!' ํ๋ฉด์ ์ฐพ์๋ค.
์ค๋๋ ํค๋ฉ๋๋ผ ๊ฝค ๋ง์ ์๊ฐ์ ๋ ๋ฆฐ ๋..
๊ฒฐ๋ก ์ ์คํ ๋ฆฌ๋ถ์ ์์ฒด webpack์ ์ฌ์ฉํด์ ๋ด๊ฐ ์ด์ฌํ ์ธํ ํ turbopack ์ค์ ๋ค์ด ์๋จนํ๋ค๋ ๊ฒ์ด์๋ค. -.-
๊ทธ๋์ ์คํ ๋ฆฌ๋ถ์ฉ svg loader๋ฅผ ๋ฐ๋ก ์ธํ ํด์ฃผ์ด์ผ ํ๋ค.
.storybook/main.ts
import type { StorybookConfig } from '@storybook/nextjs';
import type { RuleSetRule } from 'webpack'; // webpack์ module.rules ๋ฐฐ์ด์ ๋ค์ด๊ฐ๋ ํญ๋ชฉ ํ์
์ ์ ์ํ๊ธฐ ์ํจ
const config: StorybookConfig = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-onboarding',
'@chromatic-com/storybook',
'@storybook/experimental-addon-test',
],
framework: {
name: '@storybook/nextjs',
options: {},
},
staticDirs: ['../public'],
// ์ถ๊ฐ๋ก ์์ฑํ ๋ถ๋ถ
webpackFinal: async config => { // ์ต์ข
webpack ์ค์ ์ ์ปค์คํฐ๋ง์ด์งํ๋ ํจ์
if (!config?.module?.rules) return config; // config๊ฐ undefined์ด๊ฑฐ๋ ์์ผ๋ฉด ๋ฐํ
const rules = config.module.rules as RuleSetRule[]; config.module.rules ํ์
์ ์ธ (์ด ๋ฐฐ์ด์ RuleSetRule[] ํ์
์)
config.module.rules = rules.map(rule => { // ๊ธฐ์กด rules ๋ฐฐ์ด์ map์ผ๋ก ์ํํ๋ฉฐ ๊ท์น ์์
// test๊ฐ ์ ๊ท์์ธ๊ฐ && ํด๋น ์ ๊ท์์ svg ๋ฌธ์์ด์ด ํฌํจ๋์๋๊ฐ
if (rule.test instanceof RegExp && /\.svg\b/.test(rule.test.toString())) {
// ๊ธฐ์กด rule์ ๋ณต์ฌํ์ฌ exclude๋ฅผ ์ถ๊ฐ
// exclude : ์ด rule์์ svg๋ฅผ ์ ์ธํ๊ณ ๋ค๋ฅธ ํ์ผ๋ง ์ฒ๋ฆฌ (๊ธฐ์กด file-loader๊ณผ์ ์ถฉ๋ ๋ฐฉ์ง)
return { ...rule, exclude: /\.svg$/i };
}
return rule;
});
5. ๊ฒฐ๊ณผ๋ฌผ
๋ก์ปฌ ํธ์คํธ ํ๋ฉด

์คํ ๋ฆฌ๋ถ ํ๋ฉด

๊ทธ๋๋ ๊น๋ํ๊ฒ ์์ฑํด์ ๊ธฐ๋ถ์ด ์ข๋ค. ํด~
์ฐธ๊ณ
svg ์์ด์ฝ์ ๊ฒฝ์ฐ์๋ image ์ปดํฌ๋ํธ ์ฌ์ฉํด์ผํ๋์?
svg ์์ด์ฝ์ ๊ฒฝ์ฐ์๋ image ์ปดํฌ๋ํธ ์ฌ์ฉํด์ผํ๋์? - ์ธํ๋ฐ | ์ปค๋ฎค๋ํฐ ์ง๋ฌธ&๋ต๋ณ
๋๊ตฌ๋ ํจ๊ปํ๋ ์ธํ๋ฐ ์ปค๋ฎค๋ํฐ. ๋ชจ๋ฅด๋ฉด ๋ฌป๊ณ , ํด๋ต์ ์ฐพ์๋ณด์ธ์.
www.inflearn.com
Components: Image | Next.js
Optimize Images in your Next.js Application using the built-in `next/image` Component.
nextjs.org
https://react-svgr.com/docs/webpack/
SVGR - Transforms SVG into React Components. - SVGR
Transforms SVG into React Components.
react-svgr.com
https://sihun.dev/blog/nextjs15_svgr_setting
Next.js 15 + SVGR ์ธํ ๋ฐฉ๋ฒ (feat.TurboPack)
Next.js 15์์ TurboPack๊ณผ webpack์ ์ค์ ํด์ SVGR์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ด ์๋ค
sihun.dev
https://stackoverflow.com/questions/79329145/how-to-import-svg-icons-in-nextjs-15
How to import svg icons in Nextjs 15
I downloaded the Vercel Ecommerce template and want to use it with custom icons. I have installed @svgr/webpack and configured next.config.mjs: export default { images: { formats: ['image/avi...
stackoverflow.com
https://nextjs.org/docs/app/api-reference/config/next-config-js/turbopack#examples
next.config.js: turbopack | Next.js
Configure Next.js with Turbopack-specific options
nextjs.org
https://bh2980.tistory.com/276
Next.js์ Storybook์ SVGR ์ค์ ํ๊ธฐ
ํ๋ก์ ํธ์ Storybook์ SVGR ์ค์ ํ๊ธฐ ์น์คํก ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉด์ SVGR์ ์ฌ์ฉํด์ผํ ์ผ์ด ์๊ฒผ๋ค. ์ค๋์ Next.js๊ธฐ๋ฐ ํ๋ก์ ํธ์ Storybook์ SVGR์ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์ ์ด๋ณด๋ คํ๋ค. SVGR์ด๋? SVG๋
bh2980.tistory.com
SVG Icon ์ปดํฌ๋ํธ๋ก ๋ง๋ค๊ธฐ(SVGR, TS)
ํ๋ก์ ํธ๋ฅผ ์งํํ๋ฉฐ svg ํ์ผ์ ์ธ ์ผ์ด ๋๊ฒ ๋ง์๋ฐ ๋๋ svg ํ์ผ์ ์ฌ์ฉํ ๋๋ง๋ค svgr lib๋ฅผ ์ฌ์ฉํด์๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ icon์ ์ฌ์ด์ฆ๋ ์์์ด ์ ํด์ ธ์ ์ฌ์ฌ์ฉ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์์๋ค.
velog.io
'Trouble Shooting & Issues > Linkiving' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| Button ์ปดํฌ๋ํธ ๋ฆฌํฉํ ๋ง ํ๊ธฐ (0) | 2025.10.27 |
|---|---|
| [WIP]๐stories ๋ด render ํจ์๊ฐ React ์ปดํฌ๋ํธ๊ฐ ์๋ ์ผ๋ฐ ํจ์๋ก ์ธ์๋์ด useState ํ ํธ์ถ์ด ๊ธ์ง๋์ด ๋ฐ์ํ๋ ์ค๋ฅ (0) | 2025.10.27 |
| package-lock.json์ .gitignore ํด๋ ๋๋? (0) | 2025.08.12 |
| Linter๋ ์ ์ฉ์ด ์๋๊ณ ์์๋ค (0) | 2025.08.12 |
| Prettier ์ ์ฉ์ด ์๋๊ณ ์์๋ค (0) | 2025.08.12 |
GitHub