์ด๊ธฐ์ธํ ๊ธฐ๋กํ๊ณ ๊ณต์ ํ๋ ๊ฒ ์ข์ ๊ฑฐ ๊ฐ์์ ์์ฑํ์์ต๋๋ค. ์ฝ๊ณ ๊ถ๊ธํ์ ์ ์์ผ์๋ฉด ์ผ๋ง๋ ์ง ์ง๋ฌธ์ฃผ์ญ์ผ!
ํ์ ์คํฌ๋ฆฝํธ ํ ํ๋ฆฟ์ ์ง์ํด์ฃผ๊ธธ๋ ์๋ ๋ช ๋ น์ด๋ก ์ค์นํ์์ต๋๋ค.
npx create-next-app@latest --ts
typescript config ํ์ผ๋ ์์์ ํด์ฃผ๊ธธ๋ ํ์ต๋๋ค.
touch tsconfig.json
cra์ ๋ค๋ฅด๊ฒ ์๋์ ์คํฌ๋ฆฝํธ๋ก ์คํํฉ๋๋ค. ์๋ ๋ช ๋ น์ด ์น๋ฉด eslint๋ ๋ฑ๋ฑ๋ฑ... ๋ญ๊ฐ ์๋์ผ๋ก ํด์ฃผ๋ ๊ฒ ๊ฐ์์ต๋๋ค.
npm run dev
์์์ .eslintrc.json
๋ฅผ ๋ง๋ค์ด์ฃผ๊ณ ๊ฐํ ๊ท์น์ ์ ์ฉํด์ฃผ๋ ๊ฑธ๋ก ์ถ์ ๋์์ต๋๋ค.
"extends":"next/core-web-vitals"
๊ทธ๋ฐ๋ฐ ์ฝ๊ฐ ๋ถ์คํ๋ค๊ณ ๋๊ปด์ ธ์ npx eslint --init
์ผ๋ก airbnb ๊ท์น๊ณผ ๋ค๋ฅธ ํจํค์ง๋ฅผ ์ค์นํ์ฌ ๋ณด๊ฐํ์์ต๋๋ค. ์ด ๊ท์น์ด ๋๋ฌด ์๊ฒฉํด์ ๋ช๊ฐ์ง๋ ๋ฃฐ๋ก ์ ๊ฑฐํ์์ต๋๋ค.
"rules": {
"import/prefer-default-export": "off",
"react/jsx-filename-extension": [
1,
{ "extensions": [".js", ".jsx", ".ts", ".tsx"] }
],
"react/jsx-props-no-spreading": "off",
"import/extensions": 0,
"implicit-arrow-linebreak": 0,
"import/no-unresolved": 0,
"react/function-component-definition": "off"
}
์๋ ํ๋ก์ ํธ ๋ ํ๋ ๊ท์น ๊ทธ๋๋ก ์์ฑํ์์ต๋๋ค. eslint๋ ์ถฉ๋ ์๋ด๊ฒ ํด์ฃผ๋ ํจํค์ง ๋ช๊ฐ๋ฅผ ์ถ๊ฐ ์ค์นํ์์ต๋๋ค!
์ฌ์ค ์ ํฌ๋ styled-components๋ฅผ ์ฐ๊ธฐ์ ํฐ ์ธ๋ชจ๋ ์์ง๋ง readmeํ์ผ ํฌ๋ฉง์ ๊น๋ํ๊ฒ ํด์ฃผ๋๊ฒ ๋ง์์ ๋ค์ด์ ์ค์นํ์์ต๋๋ค.
{
"extends": ["stylelint-config-standard", "stylelint-config-prettier"]
}
์ธํ ์ ์ ๋ชจ๋ฅด๊ฒ ์ด์ ์ ์ ์ผ๋ก Next.js + Typescript + Styled-components ์ฝ๊ฒ ๊ตฌ์ถํ๊ธฐ ์ด ํฌ์คํ ์ ๋ฐ๋ผํ์์ต๋๋ค.
components
์์๋ ๋ฏธ๋ฆฌ ์ํ ๋ฏน ๋์์ธ ํจํด ์ ์ฉํ์์ต๋๋ค.
hook
์ปค์คํ
ํ
์ฐ๋ ๊ณณ ์
๋๋ค.
pages
์์ api
๋ ๊ธฐ๋ณธ ์ค์ ์ ์๋ ํ์ผ์
๋๋ค. ํน์ดํ๊ฒ ์ฌ๊ธฐ ์์์ api๋ฅผ ๋ชจ์๋๋ ๊ฒ ๊ฐ์์ต๋๋ค.(์์ธํ ๋ชจ๋ฆ..)
_app.tsx์ _document.tsx๋ styled-Components๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ํ์์ ์ธ ์ค์ ์ด๋ผ๊ณ ํฉ๋๋ค.
- _app.tsx๋ ์ปค์คํ app์ผ๋ก ์๋ cra์ app.tsx ๊ธฐ๋ฅ์ ํ๋ ๊ฒ์ผ๋ก ์๊ฐ๋ฉ๋๋ค...
- _document.tsx๋ styled-components๋ฅผ ์ฌ์ฉํ๋ฉด ssr์ธ nextjs์์๋ ์ด๊ธฐ ํ๋ฉด์ ์คํ์ผ์ด ์๋จนํ์ ๋จนํ๋๋ก ์ธํ ํ๋ ๊ฒ์ผ๋ก ์๊ฐ๋ฉ๋๋ค........
public
์ ์๋์ ๊ทธ ๊ธฐ๋ฅ์ ํฉ๋๋ค.
shared
๋ interpace๋ ์ ํธ ๊ฐ์ ๊ฑธ ๋ชจ์๋๋ ๊ณณ์
๋๋ค.
styles
๋ ์คํ์ผ ๊ด๋ จ๋ ๊ฒ๋ค์ ๋ชจ์๋์ต๋๋ค. ๊ธ๋ก๋ฒ ์คํ์ผ๊ณผ ํ
๋ง ์ ์ฉ ๋ง์ณค์ต๋๋ค.
color: {
veryPeri: '#6667AB',
veryPeri500: 'rgba(102, 103, 171, 0.5)',
veryPeri300: 'rgba(102, 103, 171, 0.3)',
lightViolet: '#AAB6FE',
black: '#000000',
black600: 'rgba(0, 0, 0, 0.6)',
gray: '#989898',
gray500: 'rgba(152, 152, 152, 0.5)',
gray300: '#DCDCDC',
gray100: '#F4F4F4',
gray50: 'rgba(244, 244, 244, 0.5)',
red: '#FF8A80',
},
boxShadow: {
onButton: {
default: '0px 3px 2px rgba(21, 16, 83, 0.6',
push: 'inset 0px 3px 2px rgba(21, 16, 83, 0.6)',
},
offButton: {
default: '0px 3px 2px rgba(186, 181, 201, 0.98)',
push: 'inset 0px 3px 2px rgba(186, 181, 201, 0.98)',
},
modal: '0px 2px 5px 2px rgba(0, 0, 0, 0.25)',
},
ํฌ๊ฒ ์ปฌ๋ฌ/๋ฐ์ค ์๋์ฐ๋ก ๋๋ด์ต๋๋ค. onButton์ ํ์ฑํ๋ฒํผ, offButton์ ๋นํ์ฑํ๋ฒํผ์ ๋งํ๊ณ ๋ชจ๋ฌ์ ๋ชจ๋ฌ์ ๋๋ค.
์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ช๊ฐ์ง ์ค์ ์ ํ์์ต๋๋ค.
1. _app.tsx, _document.tsx
2. .babelrc
with-styled-components-babel ์ด ๋ ํฌ๋ฅผ ์ฐธ์กฐํ์์ต๋๋ค.
next-env.d.ts
ํ๊ฒฝ๋ณ์ ํ์
์ค์ ํ์ฌ์ ์๋์์ฑ๋๊ฒ ํ๋ ํ์ผ์ธ๋ฐ, ์ฌ์ฉํ ๋ ์ฌ์ฉ๋ฒ์ ์ฝ์ด๋ณด๊ณ ์จ์ผํ ๊ฒ ๊ฐ์ต๋๋ค.
next.config.js
config ์ค์ ์ถ๊ฐ ํ๋ ๊ณณ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค. ์ํค๊ธฐ๋ ๋๋ก ์ถ๊ฐํด์ ์ค์ ์ ์ฝ์ด๋ด์ผํ ๊ฒ ๊ฐ์ต๋๋ค. ์ง๊ธ์ svg์ชฝ ์ถ๊ฐ๋์ด์๋ ๊ฑฐ ๊ฐ์ต๋๋ค?