본문 바로가기
Woowa Techcourse/Missions

Create React App(CRA) 없이 React 시작하기

by mingule 2021. 4. 16.

 

보통 처음 React App을 시작하려고 하면, Create React App(CRA)을 많이 사용한다.

귀찮은 설정들 없이도 CRA를 사용하면 React에만 집중해 개발할 수 있기 때문이다.

 

하지만 CRA 없이도 React를 사용해 Application을 충분히 잘 만들 수 있다. 

약간의 노력이 더 들어가면 ^^.. 되니깐..

어차피 사용할 꺼 내부가 어떻게 돌아가고 있는지 한번 확인하고싶을 때 이렇게 만들어 보는 것도 좋은 것 같다.

그리고 CRA는 우리가 사용하지 않는 모듈들도 많이 담고 있기 때문에, 앱 자체가 무거워진다는 단점이 있다. 그래서 Snowpack 같은 가벼운 빌드 도구가 나오기도 했지만.. 어쨌든! 우리는 이런 도구들 없이 밑바닥부터 React를 시작해보자!

 

서론은 여기까지! 아래부터는 어떻게 만드는지 작성해보겠다.

 

먼저, 원하는 곳에 폴더를 하나 만들고, 안으로 들어간다.

mkdir without-cra
cd without-cra

우리가 만들어야 할 파일들은 먼저 index.html, index.js, index.css이다. 폴더 안에 아래 친구들을 만들어준다.

// index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
  </body>
</html>
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './style.scss';

const App = () => {
  return (
    <div>
      <h1>Hello World</h1>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('root'));
h1 {
 color: red;
}

그리고 package manager로 yarn을 사용할 것이기 때문에 터미널에 yarn init을 해준다. 각 질문에 알맞은 대답을 해주면 package.json 파일이 만들어진다. 요 파일에 나중에 우리가 필요한 다른 프로젝트들에 대해 정의하게 된다. 필요한 패키지를 다운받거나 하면 여기에 들어가게 된다. 

yarn init

// 아래와 같은 질문들이 뜬다.
question name (...): 
question version (1.0.0): 
question description: 
question entry point (index.js): 
question repository url: 
question author: 
question license (MIT): 
question private: 

 

우리가 개발을 하면서 필요한 내용들, 예를 들면 prettier, eslint 혹은 cypress같은 테스트 도구들은 devDependencies에 들어가게 되고, 실제 프로젝트에서 사용될 react나 babel 등은 dependencies에 들어가게 된다. 

The difference between these two, is that devDependencies are modules which are only required during development, while dependencies are modules which are also required at runtime.

--- 간단 정리!

Dev Dependencies → 개발할 때 필요하다, 빌드나 컴파일 할 때 필요한 모듈

Dependencies → 실제 프로그램이 실행될 때 필요한 모듈

 

먼저 개발에 필요한 패키지들을 다운받겠다. 

yarn add react react-dom

yarn add -D @babel/core @babel/preset-env @babel/preset-react 

yarn add -D webpack webpack-cli webpack-dev-server

yarn add -D babel-loader style-loader css-loader

yarn add -D eslint-config-prettier eslint-plugin-prettier eslint-plugin-react

yarn add -D mini-css-extract-plugin html-webpack-plugin

먼저 우리는 리액트를 사용할꺼니까 react, react-dom을 다운받아준다. 

babel은 최신 문법을 옛날 문법으로 바꾸어줘서 보다 많은 브라우저들에서 돌아갈 수 있게 해주는 모듈이다. 

webpack은 프론트엔드 프레임워크에서 많이 사용되는 모듈 번들러이다. 이게 무슨 뜻이냐면, 웹 애플리케이션을 구성하는 몇십, 몇백개의 자원들을 하나의 파일로 병합 및 압축을 해주는 친구이다. 하나의 웹 서비스를 구성하는 파일들의 연관관계를 해석한 다음에, 그 파일들을 하나로 합쳐주는 친구다. 호호 여기에서는 깊게 다루지 않겠다 . 알고있으면 된다. 

loader는 웹팩이 관리하는 비자바스크립트 파일을 웹팩이 이해할 수 있게 해주는 역할을 한다. 

아래 eslint와 prettier는 사용 여부에 따라 선택하면 될 것 같고, 

마지막 mini-css-extract-plugin은 번들링 후 js파일에 css가 합쳐져서 나오는 게 아니라, 하나의 css 파일로 따로 분리되어 나올 수 있게 도와준다. 

 

[수정] Thanks to 🌟👍동동👍🌟 고마워요홍~~~

참고:

prettier.io/docs/en/integrating-with-linters.html

 

Prettier · Opinionated Code Formatter

Opinionated Code Formatter

prettier.io

stackoverflow.com/questions/44690308/whats-the-difference-between-prettier-eslint-eslint-plugin-prettier-and-eslint

 

What's the difference between prettier-eslint, eslint-plugin-prettier and eslint-config-prettier?

I want to use Prettier and ESLint together, but I experienced some conflicts just by using them one after another. I see that there are these three packages that seem to allow them to be used in ta...

stackoverflow.com

Prettier (Code Formatter)

개발자가 작성한 코드를 정해진 코딩 스타일을 따르도록 변환해주는 도구 

ex) 코드의 최대 길이, parameter가 한 개만 있을 때 ()로 감싸줄 것인지 아닐것인지, "를 사용할 것인지 '를 사용할 것이지 등 코드가 "pretty"하게 보이도록 하는 데에 중점을 둠

 

ESLint (Linter)

특정 스타일 규칙을 준수하지 않는 문제가 있는 소스코드를 찾는 데 사용되는 방식

- 프로그램을 실행하지 않고도 코딩 컨벤션에 위배되는 코드나 안티패턴을 자동으로 검출함

- 추가적으로 간단한 코드 Formatting (Prettier과 충돌나는 부분도 있기 때문에 그런 부분은 ignore해줘야 함)

 

→ Prettier 공식 홈페이지에 보면 use Prettier for formatting and linters for catching Bugs! 라는 말이 있다.

두개를 같이 잘 써야한다.

 

그래서 두개를 다 사용하는데, 위에서 언급한대로 Prettier과 충돌나는 부분이 있기 때문에 그런 부분들을 ignore해주는 패키지를 같이 사용해주면 좋다. 대표적인 패키지로 eslint-config-prettier, eslint-plugin-prettier가 있다. 두가지는 비슷하면서 다르다.

 

eslint-config-prettier : Turns off all rules that are unnecessary or might conflict with Prettier.

→ prettier와 충돌나는 eslint config들을 ignore(off)해줌

 

 

eslint-plugin-prettier : Runs Prettier as an ESLint rule and reports differences as individual ESLint issues.

→ prettier를 eslint에서 실행시켜서 prettier rule에 어긋나는 formatting을 마치 eslint의 에러처럼 띄워줌

그니까 prettier 규칙들을 ESLint 규칙에 추가해줌

 

config-prettier는 prettier와 충돌나는 eslint config들을 꺼준다. 그렇게 prettier과 eslint가 충돌나지 않고 잘 쓸 수 있게 해준다. 

prettier와 eslint는 각각 따로 실행된다.

 

plugin-prettier는 prettier 자체를 eslint에서 실행시켜서 만약 prettier에서 에러가 나도 eslint에서 에러를 띄워준다. 즉 eslint 안에서 prettier가 실행되고, 만약 사용자가 prettier formatting에 맞춰 코드를 짜지 않으면 eslint error가 뜬다. 

 

webpack 홈페이지에서는 아래와 같이 plugin을 굳이 추천하고 있지는 않다. 그냥 prettier --check를 쓰면 된다고 한다.

그래도 더 strict하게 사용하고 싶으면 사용하면 될 것 같다. 그래서 나는 그대로 사용하기로 결정했다.

MiniCssExtractPlugin : css를 import하는 각 JS파일마다 따로 css를 추출해 파일로 만들어줌

Style Loader : js 이외의 파일들을 읽지 못하는 웹팩을 위해 css파일을 js-style로 만들어 넣어줌 (<style> </style>을 넣어주는 것!

 

그리고 아래처럼 webpack.config.js에서 설정을 해주면 되는데.. 그 전에! 주의할 점이 있다.

웹팩에서 요 두가지는 함께 사용하지 않는 것을 권장하고 있다. (당연한 일인가?) 허허

mini-css-extract-plugin is more often used in production mode to get separate css files. For development mode (including webpack-dev-server) you can use style-loader, because it injects CSS into the DOM using multiple <style></style> and works faster.
⚠️ Do not use style-loader and mini-css-extract-plugin together.
 

MiniCssExtractPlugin | webpack

webpack is a module bundler. Its main purpose is to bundle JavaScript files for usage in a browser, yet it is also capable of transforming, bundling, or packaging just about any resource or asset.

webpack.js.org

내 생각에는 mini-css-extract-plugin과 style-loader는 결국 css파일을 로드해준다는 같은 일을 하고 있기 때문에 하나만 쓰는 것을 권장하는 것 같다. 보통 배포하는 경우에는 mini-css-extract-plugin을 많이 사용한다. css 파일을 따로 분리해주기 때문에  하지만 우리가 웹을 만들 때(development mode)에는 style을 파일에서 import하는 형식이 아니라 직접 js 안에 넣어주기 때문에 style-loader를 쓰는 것이 훨씬 빠르다. 그렇기 때문에 종종 아래와 같이 development mode와 production mode일 때를 분리해 설정해주기도 한다.

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: {
    app: ['./index.js'],
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  devServer: {
    hot: true,
    inline: true,
    host: 'localhost',
    port: 5500,
    contentBase: path.join(__dirname, '/dist/'),
  },
  module: {
    rules: [
      { test: /\.(js)$/, exclude: /node_modules/, use: 'babel-loader' },
      {
        test: /\.css$/,
        use: [
           devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader',
        ],
      },
    ],
  },
  mode: 'development',
  devtool: 'eval',
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './index.html',
    }),
    new MiniCssExtractPlugin({
      filename: 'app.css',
    }),
  ],
};

위와 같이 설정해주고, yarn start 를 하면 웹이 실행된다. localhost:5500에 들어가서 확인해보면 만든 웹이 잘 실행되고 있다는 것을 볼 수 있당. 

'Woowa Techcourse > Missions' 카테고리의 다른 글

Frontend를 위한, Socket과 WebSocket  (3) 2021.08.26
Javascript This  (1) 2021.04.27
Javascript 콜백 함수(Callback Function)  (1) 2021.04.12
Throttle, Debounce  (1) 2021.04.01
[GIT] 자주쓰는 GIT 명령어 정리  (2) 2021.03.24

댓글