์ง์ ์ ์ํ ๋ฆฌ์กํธ-ํ์ ์คํฌ๋ฆฝํธ-๋ณด์ผ๋ฌํ๋ ์ดํธ ์๊ฐ
๐ ๋ค์ด๊ฐ๋ฉฐ
์ค๋์ ํ์๊ฐ ๊ฐ๋จํ ํ๋ก์ ํธ๋ฅผ ์์ํ ๋๋ง๋ค ์ฌ์ฉํ๋ React
์ TypeScript
๋ฅผ ์ด์ฉํ ๋ณด์ผ๋ฌํ๋ ์ดํธ๋ฅผ ์๊ฐํ๊ณ ์ํ๋ค. ํด๋น ๋ณด์ผ๋ฌํ๋ ์ดํธ์ ๋งํฌ๋ ๋ค์๊ณผ ๊ฐ๋ค.
๐ ๊ธฐ๋ณธ๊ตฌ์กฐ
๊ธฐ๋ณธ์ create-react-app์ ํ์ ์คํฌ๋ฆฝํธ ํ ํ๋ฆฟ
๊ธฐ๋ณธ์ ์ผ๋ก create-react-app์ ํ์ ์คํฌ๋ฆฝํธ ํ ํ๋ฆฟ ๊ธฐ๋ฐ์ด๋ค. ํด๋น ํ ํ๋ฆฟ์ ๋ค์ ์ปค๋งจ๋๋ก ์ค์นํ ์ ์๋ค.
npx create-react-app my-app --template typescript
# or
yarn create react-app my-app --template typescript
global-styles.ts
์ ์ญ์ผ๋ก ์ฐ์ด๋ CSS ํ์ผ์ global-styles.ts
๋ผ๋ ํ์ผ๋ก ๊ด๋ฆฌํ๊ณ ์๋ค. ํด๋น ํ์ผ์๋ ๊ฐ์ข
์ ์ญ์คํ์ผ๊ณผ ์น์์ CDN ํ์ผ์ ๋ถ๋ฌ์จ๋ค. ๋ถ๋ฌ์ค๋ CDN ์ข
๋ฅ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- `normalize.css - ์ ์ญ CSS๋ฅผ normalizeํ๋ค. (โ ๏ธ reset๊ณผ ๋ค๋ฅธ ์ญํ ์ด๋ค.)
- Font Awesome - ๊ฐ์ข ์์ด์ฝ์ ์ฌ์ฉํ ์ ์๋ค..
- ๊ฐ์ข ์น ํฐํธ - ๊ตฌ๊ธ ์นํฐํธ์์ ๊ฐ์ ธ์ค๋ฉฐ ํ์ฌ ๋ฐฐ๋ฌ์๋ฏผ์กฑ ๋ํ, ์ก๋ช , ๋๋๊ณ ๋, ๋๋๋ช ์กฐ, ๋๋์๊ธ์จ ํ, ๊ฒ์๊ณ ๋๋ฅผ ์ฌ์ฉ์ค์ด๋ค.
import { createGlobalStyle } from './typed-components';
import { fontSize, color, media } from './config/_mixin';
export const GlobalStyle = createGlobalStyle`
/*
normalize.css - https://necolas.github.io/normalize.css/
*/
@import url("https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.css");
/*
Fontawesome - https://fontawesome.com/
*/
@import url("https://use.fontawesome.com/releases/v5.11.2/css/all.css");
/*
Web Fonts from Google Fonts
๋ฐฐ๋ฌ์๋ฏผ์กฑ ๋ํ - https://fonts.google.com/specimen/Do+Hyeon
์ก๋ช
- https://fonts.google.com/specimen/Song+Myung
๋๋ ๊ณ ๋ - https://fonts.google.com/specimen/Nanum+Gothic
๋๋ ๋ช
์กฐ - https://fonts.google.com/specimen/Nanum+Myeongjo
๋๋์๊ธ์จ ํ - https://fonts.google.com/specimen/Nanum+Pen+Script
๊ฒ์๊ณ ๋ - https://fonts.google.com/specimen/Black+Han+Sans
Use the following CSS rules to specify these families:
font-family: 'Black Han Sans', sans-serif;
*/
@import url("https://fonts.googleapis.com/css?family=Nanum+Gothic|Black+Han+Sans|Do+Hyeon|Song+Myung|Nanum+Myeongjo|Nanum+Pen+Script");
* {
box-sizing: border-box;
}
body{
font-family: 'Nanum Gothic', sans-serif;
font-size: ${fontSize.normalFontSize};
/* background-color: ${color.default.bgColor};
color: ${color.default.fontColor}; */
background-color: ${color.darkmode.bgColor};
color: ${color.darkmode.fontColor};
${media.giant} {
/* Giant View */
}
${media.desktop} {
/* Desktop View */
}
${media.tablet} {
/* Tablet View */
}
${media.phone} {
/* Phone View */
}
}
a{
text-decoration: none !important;
&:hover{
color: ${color.default.mainColor};
color: ${color.darkmode.mainColor};
}
}
button{
cursor: pointer;
background-color: white;
outline: none;
border: none;
&:active {
outline: none;
border: none;
}
}
/* animations */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes fadeIn {
0%{
opacity: 0;
}
100%{
opacity: 1;
}
}
`;
์ถ๊ฐ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
styled-components
๊ฐ์ธ ์์
์ ํ ์ ์คํ์ผ๊ณผ ๋ก์ง์ด ๋ถ๋ฆฌ๋๋ฉด ์์
์๋๊ฐ ํ์ ํ ์ค์ด๋ ๋ค. CSS์์์ ์ปดํฌ๋ํธ์์ state
๋ฅผ ์ฌ์ฉํ๊ณ ๋ ์ถ๊ธฐ๋ํ๊ณ , ๊ทธ๋ ๋ค๋ฉด styled-components
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
๊ฐ์ข ํฌ๋ฉํฐ
๊ธฐ์กด์ ์ฌ์ฉํ๋ ํ๋ก์ ํธ์ ์ฝ๋ฉ ๊ฒฝํ์ ๋์ผํ๊ฒ ์ ์งํ๊ธฐ์ํด 2๊ฐ์ ํฌ๋ฉํฐ๋ฅผ ์ฌ์ฉํ๋ค.
eslint
๊ฐ์ข
eslint
์ ๊ด๋ จ๋ ํจํค์ง๋ฅผ ๊น๊ณ ์ค์ ์ ํ์ฌ ์ฌ์ฉ์ค์ด๋ค.
// .eslintrc
{
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended",
"prettier/@typescript-eslint",
"plugin:prettier/recommended"
],
"plugins": ["react", "@typescript-eslint", "prettier"],
"env": {
"browser": true,
"jasmine": true,
"jest": true
},
"settings": {
"react": {
"pragma": "React",
"version": "detect"
}
},
"parser": "@typescript-eslint/parser"
}
prettier
Visual Studio Code์ Prettier ํ์ฅํ๋ก๊ทธ๋จ๊ณผ ํจ๊ป ์ฌ์ฉํ๊ณ ์๋ค.
// .prettierrc
{
"singleQuote": true,
"semi": true,
"useTabs": false,
"tabWidth": 2,
"trailingComma": "all",
"printWidth": 80,
"arrowParens": "always",
"orderedImports": true
}
๋ฒ์ ๊ด๋ฆฌ
.nvmrc
.nvmrc
ํ์ผ์ ์ด์ฉํด ํด๋น ํ๋ก์ ํธ์ ๋
ธ๋ ๋ฒ์ ์ ํต์ผํ๊ณ ์๋ค. ์ฃผ๋ก ๋
ธ๋์ LTS ๋ฒ์ ์ ์ฌ์ฉํ๊ณ ์๋ค.
// .nvmrc
13.0.1
package.json
๋ฒ์ ๊ด๋ฆฌ๋ฅผ ์ํด ์ญ์ package.json์ ์ฌ์ฉํ๋ค.
// package.json
{
"name": "react-typescript-boilerplate",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-router": "^5.1.2",
"react-scripts": "^3.3.0",
"styled-components": "^4.4.0"
},
"devDependencies": {
"@testing-library/react": "^9.3.0",
"@types/jest": "24.0.20",
"@types/node": "12.11.7",
"@types/react": "^16.9.11",
"@types/react-dom": "16.9.3",
"@types/react-router": "^5.1.2",
"@types/styled-components": "^4.1.19",
"@typescript-eslint/eslint-plugin": "^2.5.0",
"@typescript-eslint/parser": "^2.5.0",
"eslint": "^6.8.0",
"eslint-config-react": "^1.1.7",
"eslint-loader": "^3.0.2",
"tslint": "^5.20.0",
"typescript": "^3.6.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
'Web > React' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ง์ ์ ์ํ ๋ฆฌ์กํธ-ํ์ ์คํฌ๋ฆฝํธ-๋ณด์ผ๋ฌํ๋ ์ดํธ ์๊ฐ (0) | 2020.03.15 |
---|---|
๋ฆฌ์กํธ์์ ์๋ก๊ณ ์นจ์ ํด์ผ ํจ์๊ฐ ์๋ํ๋ ๊ฒฝ์ฐ (1) | 2020.03.02 |
[โReact] React Element, React Component ๊ทธ๋ฆฌ๊ณ JSX (0) | 2020.01.19 |
[โReact] ๐ถ ์ด๋ชจ์ง๋ฅผ ์ด์ฉํ ๋น๊ณ ๊ฒ์ ๋ง๋ค๊ธฐ (1) | 2019.01.31 |
[โReact] React ๊ธฐ๋ณธ ๊ฐ๋ (0) | 2018.12.26 |
React๋ก WYSIWYG ์๋ํฐ ๋ญ๋ก ์์ํ์ง? (4) | 2018.12.20 |
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
๋ฆฌ์กํธ์์ ์๋ก๊ณ ์นจ์ ํด์ผ ํจ์๊ฐ ์๋ํ๋ ๊ฒฝ์ฐ
๋ฆฌ์กํธ์์ ์๋ก๊ณ ์นจ์ ํด์ผ ํจ์๊ฐ ์๋ํ๋ ๊ฒฝ์ฐ
2020.03.02 -
[โReact] React Element, React Component ๊ทธ๋ฆฌ๊ณ JSX
[โReact] React Element, React Component ๊ทธ๋ฆฌ๊ณ JSX
2020.01.19 -
[โReact] ๐ถ ์ด๋ชจ์ง๋ฅผ ์ด์ฉํ ๋น๊ณ ๊ฒ์ ๋ง๋ค๊ธฐ
[โReact] ๐ถ ์ด๋ชจ์ง๋ฅผ ์ด์ฉํ ๋น๊ณ ๊ฒ์ ๋ง๋ค๊ธฐ
2019.01.31 -
[โReact] React ๊ธฐ๋ณธ ๊ฐ๋
[โReact] React ๊ธฐ๋ณธ ๊ฐ๋
2018.12.26