글 작성자: 택시 운전사
반응형

👋 들어가며

오늘은 필자가 간단한 프로젝트를 시작할때마다 사용하는 ReactTypeScript를 이용한 보일러플레이트를 소개하고자한다. 해당 보일러플레이트의 링크는 다음과 같다.

🏗 기본구조

기본은 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"
    ]
  }
}
반응형