내가 쓰는 Next.js 보일러 플레이트 만들기

황주현·2022년 3월 8일
6

들어가며

세상에는 게으른 사람들이 많지만, 그 중에서도 가장 게으른 건 개발자 인 것 같다. (나만 그럴수도..😅)
조금씩 더 효율적이고, 더 체계적이며, 더 간단하게 하고싶어 하기 때문이다.

이번에는 계속해서 한켠에 쌓여있던 기술부채 중 하나인 보일러 플레이트 만들기를 진행하려 한다.

아직 부족한 실력이라 다른사람들이 쓰기 위해서라기 보다는, 내가 반복해서 작업해야했던 일들을 줄여주는 역할로 사용하려 한다.

이제 만들어보자! 보일러 플레이트!!

우선은 먼저...

자 이제 만들건데..음.... 어떻게 해야 하지?? 🤨

많은 사람들이 무언가를 시작하기 전, 정리가 되지 않았을 때 가장 먼저 만나게 되는 벽이라고 생각된다.
이번에는 그런 실수를 하지 않기 위해 미리 정리하고 시작하려 한다.

필요한 요소 생각하기

결국 가장 중요한 것은 목적이라고 생각이 된다.

지금 잘 개발하고 있는데 굳이? ? 보일러플레이트를 개발하냐는 말이다.
당연한 이야기인 것 같지만 목적을 정의하고 안하고는 생각보다 큰 영향이 있다.

따라서 보일러플레이트를 만들어서 뭘 하려고 하는지 정리해보려 한다.

나는 단순 반복 작업을 하고싶지 않아서 보일러 플레이트를 만들고자 했다.
여기서 말한 단순 반복 작업 요소는 아래와 같다.

  • Next.js
  • React
  • Typescript
  • Lint
  • Styled-components
  • commitlint

이 외에도 전역상태관리 등의 기능이 있을 수 있으나, 이는 규모에 따라 달라지기 때문에 넣지 않았다.

해당 요소들은 매번 개발을 시작할 때마다 필요로 했던 것들이다.
이런 요소들의 자잘한 세팅은 개발 효율을 저하시키기 때문에, 보일러 플레이트를 만들기로 했다.

그렇다면 목적을 정했으니 한번 보일러 플레이트를 직접 만들어보자.


이제 진짜 만들어보자!

Github Repo를 template로 만들기

우선 Github Repo부터 만들고 시작해보자.

간단하게 Github Repo를 생성 후 Settings에 들어간다.

Template repository 체크박스를 클릭해 Template Repo로 만들어준다.

이제 해당 Repo는 템플릿으로 사용 가능하다.

Create-Next-app으로 Next.js, Typescript 설치

cmd 창을 열어 아래와 같이 입력해보자.

npx create-next-app --typescript
What is your project named? ... [내 프로젝트 이름]

화면을 보면 react, react-dom, next가 자동으로 설치되는 것을 볼 수 있다.

create-react-app, create-next-app 이 뭔지 모른다면 Google!


Lint 설정하기

  • Next.js
  • React
  • Typescript
  • Lint
  • Styled-components
  • commitlint

벌써 필요 요소 중 3단계를 완료하였다.
이번에 설정해 볼 것은 Lint이다.

잠깐! Lint는 뭐죠?? 처음 들어보는데..😮

개발자 분들이라면 Lint를 모를 리 없으나, 이제 막 시작하는 주니어 분들에게는 생소할 수도 있다.
Lint는 간단하게 말해서 Code를 작성하는 규칙을 정해두는 것이다.


(내 코드 작성법이 맞아!!😠)

예를들어 '세미콜론 쓰지않기', '탭 쓰지 않기', ' " " 대신 ' ' 사용하기' 등의 규칙이 있다.
이러한 규칙을 정하는 이유는, 여러 개발자들이 개발하는 환경에서 코드의 통일성을 맞추고 유지보수를 용이하게 하기 위해서 이다.

Lint를 사용하려는 주니어 개발자 분들은 우선 Google에서 Lint에 대한 개념을 잡고 오는것을 추천한다.

그럼 이제 Lint를 설정해보자.
에어비앤비 등의 유명 Lint가 있으나, 나는 typescript Lint를 적용시키기 위해 GTS : Google Typescript style을 사용한다.

GTS는 Google의 TypeScript 스타일 가이드이며, Formatter, Linter 등을 지원한다.

HandBook도 지원하기 때문에 관심있는 분들은 여기서 확인해보자.

설치는 아래 명령어로 진행한다.

npm install -D gts

또한, 추가적으로 아래 라이브러리가 필요하다.

npm install -D eslint-plugin-node eslint-plugin-prettier @typescript-eslint/eslint-plugin

하지만 해당 gts는 설치로 바로 사용할 수 없고 코드를 불러와 주어야 한다.
프로젝트 루트 폴더에서 아래 파일들을 생성해주자.


잠깐! 프로젝트 루트 폴더가 대체 어디에요??😥

간단한 내용이긴 한데... 개인적으로 개발을 처음 할 때 대체 프로젝트 루트 폴더가 어디를 의미하는건지 몰라서 허둥지둥 했었다. 나 같은 사람이 없기를 바래 참고차 적어본다.

himprover-nextjs-starter	// 프로젝트 루트 폴더 위치
├─node_modules
├─pages
│  └─api
├─public
└─styles

// node_modules, pages, public, styles 폴더와 같은 레벨에 생성!!

프로젝트 루트 폴더에 생성하라는 것은 위 구조에서 node_moudles, pages, public, styles와 같은 레벨의 위치에 생성하라는 뜻이다!
간단한 내용이지만 한번 더 짚고 넘어갔다


프로젝트 루트 폴더.prettierrc.js.eslintrc.json(아마 이건 이미 존재)를 만들어 아래와 같이 작성해준다. 해당 내용은 gts 라이브러리의 설정 파일을 불러오는 과정이라고 보면 된다.

// .prettierrc.js
module.exports = {
  ...require('gts/.prettierrc.json'),
};
// .eslintrc.json
{
  "extends": ["./node_modules/gts/", "next/core-web-vitals"],
  "env": {
    "browser": true,
    "jest": true,
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  }
}

그런데 이렇게만 적으면 vscode가 에러를 보여준다.

Delete `␍`eslintprettier/prettier
'React' must be in scope when using JSXeslintreact/react-in-jsx-scope

(헉 어떡하지...🙄)

다행히 이는 .eslintrc.json에 코드 두 줄만 추가해주면 해결된다. eslint 설정과 현재 프로젝트가 충돌이 났다고 보면 된다.

//	.eslintrc.json
{
  "extends": ["./node_modules/gts/", "plugin:react/recommended"],
  "rules": {
    "react/react-in-jsx-scope": "off",						// 추가
    "prettier/prettier": ["error", {"endOfLine": "auto"}]	// 추가
  },
  "env": {
    "browser": true,
    "jest": true
  },
  "settings": {
    "react": {
      "version": "detect"
    }
  }
}


이제 문제없이 보여지는 것을 확인할 수 있다.


Styled-components 적용하기

  • Next.js
  • React
  • Typescript
  • Lint
  • Styled-components
  • commitlint

이번에는 styled-components 적용을 진행한다. 거의다왔다!!

어.....그....Styled-components는 뭐죠?? 😓

styled-components 는 스타일 라이브러리 중 하나로 CSS-in-JS 형태의 스타일 방식을 지원한다.

내가 가장 많이 쓰는 style 라이브러리이고, Nextjs 에서 SSR로 사용하려면 별도의 설정을 매번 해주어야 하기 때문에 필수 요소로 잡았다.

아래 명령어로 필요 라이브러리를 설치하자.

npm install styled-components
npm install -D @types/styled-components

만약 순수 React만 사용하거나, Nextjs에서 SSR를 사용하지 않으면 해당 단계에서 끝이다.

하지만 우리는 SSR도 사용한다고 가정하고 해당 설정도 진행해준다.
바벨 설정을 통해 styled-components에 SSR를 사용할 수 있다.

아래 명령어로 설치 후 루트 폴더에 .babelrc를 생성하여 아래와 같이 입력해준다.

npm install -D babel-plugin-styled-components
// .babelrc
{
  "presets": ["next/babel"],
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "fileName": true,
        "displayName": true,
        "pure": true,
        "ssr": true
      }
    ]
  ]
}

다음으로 pages 폴더 내에 _document.tsx 를 생성해 아래와 같이 입력한다.

// pages/_document.tsx
import Document, {
  Html,
  Head,
  Main,
  NextScript,
  DocumentContext,
} from 'next/document';
import {ServerStyleSheet} from 'styled-components';

class MyDocument extends Document {
  static async getInitialProps(ctx: DocumentContext) {
    const sheet = new ServerStyleSheet();
    const originalRenderPage = ctx.renderPage;
    try {
      ctx.renderPage = () =>
        originalRenderPage({
          enhanceApp: App => props => sheet.collectStyles(<App {...props} />),
        });

      const initialProps = await Document.getInitialProps(ctx);
      return {
        ...initialProps,
        styles: (
          <>
            {initialProps.styles}
            {sheet.getStyleElement()}
          </>
        ),
      };
    } finally {
      sheet.seal();
    }
  }

  render() {
    return (
      <Html>
        <Head></Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

export default MyDocument;

(번외) Global-styles Normalize, Theme 설정

위 과정까지 진행하면 설치는 끝이 났으나, 기본적으로 개발 할 때 사용하는 Normalize와 Theme 설정까지 해보려고 한다.

우선 아래와 같이 라이브러리를 설치한다.

npm install styled-normalize

그리고 styles 폴더를 생성해 global-styles.ts라는 파일을 하나 만들자.
(폴더명, 파일명 달라도 됨)

그리고 아래처럼 작성해주자.

// styles/global-styles.ts
import {createGlobalStyle} from 'styled-components';
import {normalize} from 'styled-normalize';

export const GlobalStyle = createGlobalStyle`
    ${normalize}
`;

그 다음 pages 폴더의 _app.tsx 파일을 아래와 같이 수정해주자.
(_app.tsx는 Nextjs에서 _document.tsx와 함께 먼저 실행되는 코드이다.)

// pages/_app.tsx
import type {AppProps} from 'next/app';
import {ThemeProvider} from 'styled-components';
import {GlobalStyle} from '../styles/global-styles';
import {lightTheme} from '../styles/theme';

function MyApp({Component, pageProps}: AppProps) {
  return (
    <ThemeProvider theme={lightTheme}>
      <GlobalStyle />
      <Component {...pageProps} />
    </ThemeProvider>
  );
}

export default MyApp;

이제 정말 styled-components 설정이 끝이 났다!


commitlint 설정하기

대망의 마지막! commitlint 설정이다.

commitlint면... 뭔가 lint와 관련 있을 것 같은데..🙄

맞다. 물론 의존하고 있는 것은 아니지만 개념이 비슷하다.
lint가 개발한 코드의 규칙을 확인한다면, commitlint는 github commit 메세지의 컨벤션을 검사한다.

해당 패키지의 필요 이유도 많은 개발자들과의 협업, 명확한 커밋 메세지 작성 등이 있다.

그럼 이제 아래 명령어로 commitlint를 설치해보자.

npm install -D @commitlint/cli @commitlint/config-conventional

그리고 루트 디렉토리에 commitlint.config.js파일을 추가해 아래 내용을 작성해준다.

module.exports = {extends: ['@commitlint/config-conventional']};

이 때 해당 convention의 세부 내용은 여기서 확인 가능하다.


그럼 일단 commitlint의 설치 및 설정이 끝났다. 하지만 뭔가 부족하다.
commitlint만 단독사용하게 된다면 실제로 개발 할 때 굉장히 불편하게 사용해야 한다.
commit을 하고 명령어를 입력해 검사를 하고, 잘못되었으면 수정을 하는 등의 단계를 하자니 차라리 안하고 말 것 같다.

다행히 이러한 점을 보완해주기 위한 많은 방법들이 있다.
나는 그 중 husky라는 라이브러리를 사용해 git hook을 제어 할 것이다.


husky?

(댕댕이 아님)

huskygit hook을 쉽게 제어하는 라이브러리다.
여기서 git hook은 git에서 커밋, 푸시 등의 이벤트를 발생시켰을 때 이를 감지하고 커스텀 코드를 실행시키는 기능이다.

그럼 우선 아래 명령어로 husky를 설치해보자

npx husky-init
npm install

그리고 package.json파일 을 보면 아래 스크립트가 추가되어 있다.

이제 husky를 설정해주자.
나는 commit을 할 때 commitlint가 작동되어 commit convention을 체크해줬으면 한다.

이를 위해서는 아래 명령어를 실행해주자.

npx husky add .husky/commit-msg //윈도우는 / 대신 \ 사용

그럼 .husky 폴더 안에 commit-msg 파일이 생성되는데, 이를 아래 내용과 같이 변경해주자.

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx --no-install commitlint --edit $1

설정은 이제 끝났다. 한번 테스트를 해보면?

subject 비어있고 type 내용이 이상해 다시써와 라는 메세지를 준다.

이제 컨벤션에 맞춰 다시 작성하면?

commitlint 적용 성공!! 🤗

짠, 정상적으로 commit이 완료되었다.
저기 보이는 Error는 test파일이 없어서 생기는 오류이므로 무시해도 된다.

정리하기

자, 이제 내가 사용 할 템플릿을 완성했다.
이것저것 세팅을 많이 했다보니, 한눈에 볼 수 있도록 정리하려고 한다.

링크

https://github.com/himprover/himprover-nextjs-starter

디렉토리 구조

  • .husky : husky 라이브러리 관련 설정
  • components : 컴포넌트 파일, 유닛 테스트 파일
  • pages : 페이지 파일, 엔드포인트 테스트 파일
  • styles : 글로벌 스타일, 테마 파일 (styled-components)

파일 설정 내용

  • pages/_app.tsx : styled-components의 global-style이나 theme 설정
  • pages/_document.tsx : styled-components의 SSR 사용 위한 설정
  • .babelrc : styled-components의 SSR 사용 위한 설정
  • .eslintrc.json, .prettierrc.js : GTS:Google TypeScript 코드 스타일 사용 위한 설정
  • commitlint.config.js : commitlint 라이브러리 사용 위한 컨벤션 설정

끝! 😎

드디어 Nextjs 보일러 플레이트 만들기 설치부터 설정까지 완료되었다.
처음 시작할 땐 별 것 아닐 것 같았는데, 정리하면서 해보니 마냥 쉽지많은 않았다.

아직 부족한 부분이 많아서 차근차근 업데이트하며 완성도를 높여가야겠다.

+ 읽어주셔서 감사합니다.
+ 오타, 내용 지적, 피드백을 환영합니다. 많이 해주실 수록 제 성장의 밑거름이 됩니다.

Reference

husky로 git hook에 conventional commit 적용하기_by WANZA

profile
반갑습니다. 프론트엔드 개발자 황주현 입니다. 🤗

0개의 댓글