ํ๋ก์ ํธ๊ฐ ๊ท๋ชจ๊ฐ ์ปค์ง๊ณ ๋์ค๊ฐ ๊น์ด์ง๋ฉด์ ํ์ผ์ import ํด์ฌ๋๋ง๋ค ๋ฒ๊ฑฐ๋ก์์ก๋ค. ../
์ด 4๊ฐ๋ผ๋. ํ์
์คํฌ๋ฆฝํธ ๋ฆฌ์กํธ ํ๊ฒฝ์์ ์ ๋๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ธํ
์ ํด๋ณด์๋ค. ์ด๋ฒ ๊ธ์ ๊ทธ ์ฝ์ง์ ๊ธฐ๋ก.
import { useAppDispatch } from '../../../../store/app/hooks';
import { dispatchItemName } from '../../../../store/slices/challengePayloadSlice';
import a1 from '../../../../assets/icons/itemName/a1.svg';
1. Craco๋ก config ๊ฑด๋๋ฆฌ๊ธฐ
์ ๋๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ webpack์ config๋ฅผ ๊ฑด๋๋ ค์ผ ํ๋ค. CRA๋ก ํ๋ก์ ํธ๋ฅผ ์์ฑํ๋๋ผ๋ eject๋ฅผ ํตํด config ํ์ผ์ ๊บผ๋ด์ ์์ ํ ์ ์์ง๋ง, ํ๋ฒ ๊บผ๋ด๋ฉด ๋ค์ ๋ชป๋์๊ฐ๋ค๊ณ ๋ฆฌ๋๋ฏธ์์ ๊ทธ๋ ๊ฒ ๊ฒ์ ์ฃผ์๋..
์ซํํ ๋ปํ ๋๋ฅผ ์ํ CRACO(create react app configuration override) ๋ผ๋ ํจํค์ง๊ฐ ์๋ค. eject๋ฅผ ํ์ง ์๊ณ ๋ ์นํฉ์ ๊ฑด๋ค ์ ์๋๋ก ๋์์ค๋ค.
$ yarn add @craco/craco
$ yarn add craco-alias -D
ํจํค์ง๋ฅผ ์ค์นํด์ค๋ค.
package.json
{
...
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"eject": "react-scripts eject"
},
...
}
react-script ๋ก ๋์ด์๋ ๋ถ๋ถ์ craco๊ฐ ํด๋น ๋ช ๋ น์ด๋ฅผ ์คํํ๋๋ก ๋ณ๊ฒฝํด์ค๋ค.
craco.config.js
const CracoAlias = require('craco-alias');
module.exports = {
plugins: [
{
plugin: CracoAlias,
options: {
source: 'tsconfig',
baseUrl: './',
tsConfigPath: './tsconfig.paths.json',
},
},
],
};
root ๋๋ ํ ๋ฆฌ์ craco.config.js
์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ํ์ผ์ ์์ฑํด์ค๋ค. craco-alias
source
: 'options', 'jsconfig', 'tsconfig' ์ค ํ๋๋ฅผ ์ ํํ๋ค.baseUrl
: alias๋ฅผ ์ํ base url์ ์ค์ ํ๋ค.tsConfigPath
: tsconfig ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ๋ฃ๋๋ค. source๊ฐ 'tsconfig'๋ก ์ค์ ๋์ด ์์ ๋๋ง ํ์ํ ์ต์ .
2. ์ด์ , ๊ฒฝ๋ก ์ค์
โโโ .github # PRํฌํ๋ฆฟ, ์ก์
์ํฌํ๋ก์ฐ ๊ด๋ จ
โโโ .storybook # ์คํ ๋ฆฌ๋ถ ์ธํ
โโโ public
โโโ src
โ โโโ assets # ์์ด์ฝ, ์ด๋ฏธ์ง, ํฐํธ ํ์ผ ๋ฑ
โ โโโ components # ์ปดํฌ๋ํธ ๊ด๋ จ ํ์ผ
โ โ โโโ common
โ โ โโโ [...]
โ โโโ hooks # ์ปค์คํ
ํ
โ โ โโโ api
โ โ โโโ common
โ โ โโโ [...]
โ โโโ lib
โ โ โโโ api # axios ์ค์
โ โ โโโ styles # GlobalStyle, ThemeProvider ๊ด๋ จ
โ โ โโโ types # type, interface ๊ด๋ จ
โ โ โโโ utils # ์ ํธ ํจ์ ๊ด๋ จ
โ โโโ pages # ํ์ด์ง ๊ด๋ จ ํ์ผ
โ โโโ store
โ โ โโโ app # store ์ธํ
โ โ โโโ slices # RTK slice ํ์ผ ์์ฑ
โ โโโ App.tsx
โ โโโ index.tsx
โโโ ๊ฐ์ข
์ธํ
ํ์ผ๋ค๊ณผ ๋ฆฌ๋๋ฏธ ํ์ผ
src ๋๋ ํ ๋ฆฌ ํ์์ ์๋ ๋๋ ํ ๋ฆฌ๋ง๋ค alias๋ฅผ ์ง์ ํด์ฃผ์๋ค. ํ์ฌ ํ๋ก์ ํธ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ ์ด๋ ๊ฒ ๋์ด์๋๋ฐ, ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ importํ ์ผ์ด ๊ฑฐ์ ์๋ pages๋ฅผ ์ ์ธํ๊ณ ๋๋จธ์ง ๋ค์ฏ๊ฐ ๋๋ ํ ๋ฆฌ์ ์ ์ฉ์ํฌ ์์ .
tsconfig.paths.json
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@assets/*": ["src/assets/*"],
"@components/*": ["src/components/*"],
"@hooks/*": ["src/hooks/*"],
"@lib/*": ["src/lib/*"],
"@store/*": ["src/store/*"]
}
}
}
root ๋๋ ํ ๋ฆฌ์ tsconfig.paths.json
์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ํ์ผ์ ์์ฑํด์ค๋ค. baseUrl์ src๋ก ๋ฃ๊ณ ์๋ path์์ src๋ฅผ ๋นผ๋ ๋์ง๋ง ์ต๋ํ ์ฐธ๊ณ ํ ๊ธ ๊ทธ๋๋ก..! ๋ ์ง๊ด์ ์ผ๋ก ๋ณด์ฌ์ ์ข๋ค.
tsconfig.json
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src", "src/custom.d.ts", "craco.config.js"]
}
tsconfig.json
ํ์ผ๋ ์์ ํด์ค๋ค. ํ์
์คํฌ๋ฆฝํธ ํ๋ก์ ํธ๋ฅผ ์ปดํ์ผํ๋๋ฐ ํ์ํ ๋ฃจํธ ํ์ผ๊ณผ ์ปดํ์ผ๋ฌ ์ต์
์ ์ง์ ํด์ฃผ๋ ํ์ผ์ด๋ค.
extends
: ๋ค๋ฅธ ํ์ผ์ ์ค์ ์ ์์include
: ์ปดํ์ผ ํ ๋ ํฌํจํ ํด๋๋ ํ์ผ
๊ฐ๊ฐ ์์์ ์์ฑํ tsconfig.paths.json
๊ณผ craco.config.js
์ ์ถ๊ฐํ๋ค. extends๋ก ๋ฐ์ง ์๊ณ ๋ฐ๋ก tsconfig ๋ด์์ ์์ฑํด๋ ๋ ๋ฏ?
์ด๋ผ?
๋ถ๋ช
ํ ๋์ผ ํ ํ
๋ฐ, ๊ณ์ ๋ชจ๋์ ์ฐพ์ ์ ์๋ค๋ ์นํฉ ๋น๋ ์ค๋ฅ๊ฐ ๋ฌ๋ค. ์ ๊น ๋นํฉํ๋ค๊ฐ ์ด์ ์ ๊ธฐ์ต์ ์ด๊ธ์ด๊ธ ์ง์ด yarn.lock
์ ์ญ์ ํ๊ณ yarn start ๋ช
๋ น์ด๋ก ์คํํ๋ ์ ์์ ์ผ๋ก ๋์๋ค.
import { useAppDispatch } from '@store/app/hooks';
import { dispatchItemName } from '@store/slices/challengePayloadSlice';
import a1 from '@assets/icons/itemName/a1.svg';
์ด๋ ๊ฒ ์์ฃผ ๊น๋ํ๊ณ ๋ช ์์ ์ผ๋ก importํ ์ ์๊ฒ ๋์๋ค.
3. Storybook์์
๊ธฐ์ ๋ง์์ผ๋ก ์คํ ๋ฆฌ๋ถ์์๋ ๋๋ ํ์ธํด๋ณด๋ (๋น์ฐํ) ๋ ๋ฆฌ๊ฐ ์๋. ์คํ ๋ฆฌ๋ถ์์ ๋น์ฐํ ๋ณ๋๋ก ๋น๋ํ๊ธฐ ๋๋ฌธ์ ์นํฉ ์ค์ ์ ๋ฐ๋ก ํด์ค๋ค.
yarn add --dev tsconfig-paths-webpack-plugin
์์ ํจํค์ง๋ฅผ ์ค์นํ๋ค. tsconfig์ paths์์ ์ง์ ๋ ์์น์ ์๋ ๋ชจ๋์ ๋ก๋ํ ๋ ์ฌ์ฉํ๋ค๊ณ ๋ฌธ์์ ์จ์๋๋ฐ ๋ฌด์จ ๋ง์ธ์ง๋ ์ ๋ชจ๋ฅด๊ฒ ๋ค.
.storybook/main.js
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const path = require('path');
module.exports = {
stories: [...],
addons: [...],
webpackFinal: async (config) => {
config.resolve.plugins.push(
new TsconfigPathsPlugin({
configFile: path.resolve(__dirname, '../tsconfig.json'),
}),
);
return config;
},
framework: '@storybook/react',
core: {
builder: '@storybook/builder-webpack5',
},
};
main.js
์์ ์ค์ ์ ๋ณ๊ฒฝํด์ค๋ค. ํด๋น ํ๋ฌ๊ทธ์ธ์ผ๋ก ์ง์ ๊ฒฝ๋ก๋ฅผ ์ค์ ํด์ ๊ฐ์ ธ์ค๊ฒ ํ๋ ๊ฒ..?
์๊ฐ๋ณด๋ค ์ค๋๊ฑธ๋ ธ๋ค.
์ถ๊ฐ
์ก์ ๋ก๊ทธ๋ฅผ ๋ณด๋ ์คํ ๋ฆฌ๋ถ ๋ฐฐํฌ์ ์๋ฌ๊ฐ ๋์์๋ค. ๋ฌด์จ์ผ์ธ๊ฐ ํ๋...
์์์ ์ค์นํ๋ craco์ react-script์ ์์กด์ฑ ๋ฌธ์ ์๋ค. peer dependencies๋ ๋ด๊ฐ ๋ค๋ฅธ ํจํค์ง์ ํน์ ๋ฒ์ ๊ณผ ํธํ๋๋ค๋ ๊ฒ์ ๋ปํ๋ค. package.json์์ react-script์ ๋ฒ์ ์ด 5.0.1์ด๋ผ๊ณ ๋ช ์๋์ด ์๋๋ฐ, craco์ dependency์๋ ^4.0.0์ด๋ผ๊ณ ๋ช ์๋์ด ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ.
๋๋ค์ ๋ธ๋ก๊ทธ์๋ ์ ๊ธฐ ๋ก๊ทธ์ ๋์ ์๋ ๊ฒ ์ฒ๋ผ --legacy-peer-deps ์ต์ ์ ๋ถ์ฌ์ ์ค์น๋ฅผ ํ๋ผ๊ณ ๋์ ์๋ค. ๊ทผ๋ฐ ์ฌ์ค ์ด์ ๊ณ ์ค๋ฝ ํ๋ก์ ํธ์์ ์คํ ๋ฆฌ๋ถ ๋ฐฐํฌํ๋ฉด์ @mdx-js/react ํจํค์ง๋ฅผ ์ค์นํ๋๋ฐ ๋น์ทํ ์๋ฌ๊ฐ ์์๋ค. ๊ทธ ๋ ์ ๋ ๊ฒ ํ๋ค๊ฐ ์๋์ ๊ฒฐ๊ตญ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ์์ ํ๊ธฐ ๋๋ฌธ์, ์ ์ต์ ์ ๋ฃ์ด์ ํ๋ ๋ฐฉ๋ฒ ์ธ์ ๋ค๋ฅธ๊ฑธ ์ฐพ์๋ณด๋ ค ํ์.
npm ๋์ yarn ๋ช ๋ น์ด๋ฅผ ์ฐ๋ฉด ๋๋ ๊ฒฝ์ฐ๊ฐ ์๋ค. ์ฐธ๊ณ ๋ก์ปฌ์์ ์คํํ ๋ yarn์ ํญ์ ์ฐ๊ธฐ ๋๋ฌธ์ ๋ฐ๊ฒฌํ์ง ๋ชปํ๋? ๊ทธ๋ ๋ค๊ธฐ์ ํฐ๋ฏธ๋์ ์๋ฌด๋ฐ ๊ฒฝ๊ณ ๋ ๋จ์ง ์์๋๋ฐ. ํ . ๋ฏธ์คํ ๋ฆฌ๋ค. ํ์ง๋ง ์ปดํจํฐ๋ ๊ฑฐ์ง๋ง์ ํ์ง ์์ผ๋๊น.
name: Build & Deploy Storybook
on:
push:
branches: [dev]
paths: ['src/components/**']
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install and Build ๐ง
# This needs an Acces Token stored as "GH_TOKEN" ๐
run: |
yarn install
yarn deploy-storybook -- --ci
env:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
์คํ ๋ฆฌ๋ถ ๋ฐฐํฌ์ฉ yml ํ์ผ์ ์์ ๊ฐ์ด ์์ ํด์ฃผ์๋ค. npm์ด ์๋๋ผ yarn ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๋๋ก. dev๋ก ํธ์ฌํด์ ํ์ธํด๋ณด๋ ๋ฐฐํฌ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์๋๋ค. ๋ฌผ๋ก ๋๊ฐ์ด ๋ฒ์ ๋ค๋ฅด๋ค๋ ๊ฒฝ๊ณ ๊ฐ ๋จ๊ธด ํ์ง๋ง ๋คํ์ด ๊ฒฝ๊ณ ์ ๋์์ ๋์ด์๋ค. ์, ๊ทธ๋ผ ๋์ปค๋ก ๋ฐฐํฌํ ๋๋ npm๋ง๊ณ yarn ์ผ๋ก ๋ฐ๊ฟ์ผ๋๋๊ฑฐ๊ฒ ๋ค.