[Personal Portfolio] 1. CRA 없이 리액트 앱 시작하기

2020. 8. 17. 19:29Project

왜 CRA 를 사용하지 않으려고 했나?


최근 이머시브 과정을 수료하고, 본격적으로 취업 준비에 들어가기에 앞서서 개인 포트폴리오 사이트를 다시 만들기로 결정했다.
이전에 진행했던 4주 프로젝트를 진행하며 보일러플레이트 코드를 사용하지 않고 리액트 개발 환경을 셋팅해보고 싶다는 생각이 들었고, 추가적으로 webpack, babel에 대해서 조금 더 깊이 알아보고 싶었다.
그래서 가볍게 만질 수 있으면서, 예전부터 다시 한 번 만들어야겠다고 생각했던 개인 포트폴리오 사이트의 기초 셋팅을 밑바닥부터 구성해보게 되었다.

 

그래서 결정된 사항


  1. Create React App을 사용하지 않는다.
  2. React, SASS에 대응하는 Webpack, Babel 설정을 직접 해 본다.
  3. ESLint 설정을 해 본다.

 

초기 셋팅에 필요한 패키지들


  1. react, react-dom
  2. webpack, webpack-dev-server, webpack-cli
  3. @babel/core, babel-loader, @babel/preset-react, @babel/preset-env
  4. html-loader, css-loader, style-loader
  5. node-sass, sass-loader
  6. html-webpack-plugin

 

babel 설정하기


babel

babel은 자바스크립트 컴파일러로, 최신 자바스크립트 문법을 브라우저가 이해할 수 있는 문법으로 변환해주는 역할을 한다.

 

react 프로젝트를 위한 babel 셋팅

 


먼저, 바벨 셋팅을 위해 .babelrc 파일을 프로젝트 루트 경로에 만들었다.

{ "presets": ["@babel/env", "@babel/react"] }

그리고 위와 같이 셋팅해주었다.
babel은 babel 그 자체로만은 동작하지 않고, preset, plugin을 추가해 babel에게 어떤 dependency를 사용하는지 알려 주어야, 해당 dependency의 코드를 브라우저가 이해할 수 있도록 변환시켜준다.
내 경우에는 최신 자바스크립트 문법을 사용하는 React 프로젝트이므로, ES6 코드를 위해 @babel/preset-env 를, React 코드의 변환을 위해 @babel/preset-react 플러그인을 각각 설치하고, .babelrc 파일에 설정을 추가해주었다.

 

webpack 설정하기


webpack

webpack 공식 홈페이지에서는 webpack을 최신 자바스크립트 어플리케이션을 위한 정적 모듈 번들러 라고 소개하고 있다.
모듈 번들러는 JavaScript 모듈을 브라우저에서 실행할 수 있는 단일 JavaScript 파일로 번들링해주는 역할을 한다.
모듈 번들러를 사용하면, 코드의 종속성 관계를 관리하고, 종속성 순서대로 로딩할 수 있도록 해 준다.

 

주요 webpack 프로퍼티들

  • entry : 웹팩이 번들링을 시작할 엔트리 포인트가 될 파일
  • output : 번들링이 된 정적 파일을 어디에 생성할 것인지 셋팅
  • modules : 어떤 모듈을 어떤 식으로 번들링하고, 로딩할지 셋팅

 

react 프로젝트를 위한 webpack 셋팅

 

1. 웹팩 셋팅을 위해 webpack.config.js 파일을 프로젝트 루트 경로에 만들었다.

2. entry와 output 경로를 설정해주었다. 

const path = require("path");

module.exports = {
  entry: "./src/index.jsx",
  output: {
    path: path.join(__dirname, "/dist"),
    filename: "main.js",
  }
};

 

3. jsx / html / scss을 어떻게 번들링할 것인지 설정해주었다.

const path = require("path");

module.exports = {
  entry: "./src/index.jsx",
  output: {
    path: path.join(__dirname, "/dist"),
    filename: "main.js",
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.html$/,
        use: ["html-loader"],
      },
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  }
};
  • 여기에서 scss 파일 부분의 loader 들을 보면, [“style-loader”, “css-loader”, “sass-loader”] 순으로 설정되어 있다.
  • loader를 작성할 때 주의해야 할 점은, 끝에서부터 역순으로 실행된다는 점이다.
  • 위의 경우에는 sass-loader 가 가장 먼저 실행되어 scss 파일을 읽어 css 파일로 변환해주고, 다음으로 css-loader, style-loader 순서로 실행된다.

 

4. webpack이 html 파일을 읽을 수 있도록 해주는 html-webpack-plugin 을 설치하고, 셋팅한다. 

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: "./src/index.jsx",
  output: {
    path: path.join(__dirname, "/dist"),
    filename: "main.js",
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.html$/,
        use: ["html-loader"],
      },
      {
        test: /\.scss$/,
        use: ["style-loader", "css-loader", "sass-loader"],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
};
  • #root div가 존재하는 index.html을 읽어오는 역할을 한다.

 

결과적으로…


 

 

react를 위한 jsx 파일, #root div가 존재하는 index.html 이외에도 scss 파일이 잘 번들링되는지 시험해봤는데, 위와 같이 잘 실행된다.

 

start 스크립트는 webpack-dev-server --mode development --open --hot

build 스크립트는 webpack --mode production

로 설정했다.

startwebpack-dev-server --hot은 코드를 수정하고 저장하면 자동으로 리액트 앱이 리로딩되도록 해준다.

 

 

 

참고한 자료:

https://webpack.js.org/concepts/

https://medium.com/@krpeppermint100/js-react%EC%99%80-webpack-6ba46f84b327