[velog 클론 코딩 개발기 - 1 ] Webpack, Babel 이용해 React + Typescript 개발 환경 구성

Yeojin Choi·2021년 10월 18일
0

velog 클론코딩

목록 보기
1/5

안녕하세요! 저는 그동안 React 개발 환경을 구성하기 위해 CRA (create-react-app) 을 사용하거나, 회사에서는 다른 사람이 셋팅해줬던 개발 환경을 그대로 따라하기만 했었는데요!

그러다 보니까 번들링된 결과물은 어떻게 떨어지는지, 환경설정을 바꾸고 싶은데 어디서부터 바꿔야할지 도통 감이 잡히지 않았습니다...

그래서 저는 토이 프로젝트를 진행하며 CRA 를 쓰지 않고 Webpack, Babel 을 이용해 React + Typescript 개발 환경을 직접 설정해보자! 라는 결심을 하게 되었고!

기록으로 남길 겸, 여러분들에게 공유하고 피드백을 받고자 글로 작성하게 되었습니다 :)

0. 준비...

  1. Node.js를 설치해주시고, npm init 을 통해 package.json 파일을 생성해주세요.
  2. 폴더를 생성하고 파일을 생성하겠습니다. 저의 프로젝트 폴더 구조는
    • conf
    • dist
    • public
    • src

Webpack

Webpack 설치

  • npm i -D webpack webpack-cli
  • webpack 은 개발할 때만 필요하므로, -D 옵션으로 설치합니다.

Babel 설치

다음은 Babel을 설치하고, 설정해보겠습니다.

Babel은 리액트의 JSX, 타입스크립트와 같은 정적 타입 언어, 코드 압축, 제안(proposal) 문법 을 사용할 수 있게해줍니다.

npm i -D @babel/core @babel/plugin-proposal-class-properties @babel/preset-typescript @babel/preset-env @babel/preset-react babel-loader

//conf/babel.conf.js
module.exports = {
    presets: ["@babel/preset-env", "@babel/preset-typescript","@babel/preset-react"]
};

Webpack configuration

설정 전에, 어떤 속성들을 설정할 수 있는지 알아보고 가겠습니다!

entry

webpack 이 디펜던시 그래프를 생성하기 위해 사용해야하는 모듈, 즉 번들링의 시작점

module.exports = {
	entry: './src/index.js'
}

src 폴더의 index.js 파일을 번들링을 시작하는 파일로 지정합니다.

output

생성된 번들을 내보낼 위치와 파일 이름 지정, 기본값 ./dist/main.js

const path = require("path");

module.exports = {
    entry : "./src/index.js",
    output: { // 번들링 결과물을 내보내는 방법과 관련된 옵션
        path: path.resolve(__dirname,'dist'),
        filename: "index.js",
    }
}

pathfilename 속성으로 번들의 이름을 index.js 로 설정하고, 내보낼 위치는 dist 폴더라고 알려주었습니다.
path 모듈은 파일 경로를 지정하기위해 사용되는 core Node.js 모듈입니다. path.resolve 는 절대경로 문자열을 반환해줍니다.
__dirname 은 현재 디렉토리를 의미합니다.

loaders

Webpack 은 Javascript 와 JSON 파일만 이해합니다. 로더를 사용하면 다른 유형의 파일을 웹팩이 이해하도록 할 수 있습니다.

const path = require("path");

module.exports = {
    entry : "./src/index.js",
    output: {
        path: path.resolve(__dirname,'dist'),
        filename: "index.js",
    },
    module: { 
        rules: [
            {
                test: /\.html$/,
                use: 'html-loader'
            }
        ]
    }
}

test 속성은 변환이 필요한 파일을 식별하고, use 속성은 변환을 수행하는데 사용되는 로더를 가리킵니다.

Plugins

플러그인의 역할은 번들 최적화, 애셋 관리, 환경 변수 주입 등과 같은 역할을 수행합니다.
require() 을 통해 플러그인을 요청하고, plugins 배열에 추가해야 사용할 수 있습니다.

const path = require("path");

module.exports = {
    entry : "./src/index.js",
    output: {
        path: path.resolve(__dirname,'dist'),
        filename: "index.js",
    },
    module: { 
        rules: [
            {
                test: /\.html$/,
                use: 'html-loader'
            }
        ]
    },
  	plugins: [
        new HtmlWebpackPlugin({
            template: './public/index.html',
            filename: 'index.html'
        })
    ]
}

위 코드에서 사용된 HTML 플러그인은 생성된 모든 번들을 자동으로 삽입해 HTML 파일을 생성하는 역할을 합니다.

Mode

Mode 속성으로 development(기본값),production,none 을 설정하여 환경별로 최적화할 수 있습니다.

직접 설정해보기

webpack.config.js 파일 하나로 설정을 적용할 수 있지만, dev/prod mode 에 따라 다른 설정을 적용하고 싶었습니다.

그래서 저는 webpack.common.conf.js (공통), webpack.development.conf.js (개발용), webpack.production.conf.js (배포용) 세 파일로 설정을 관리할 것입니다!

conf 폴더로 세 파일을 이동시켜주겠습니다.

그리고 여러개로 나뉘어진 웹팩 설정 파일을 하나로 병합해주기 위해, webpack-merge 을 사용하도록 하겠습니다.

npm i -D webpack-merge 를 통해 webpack-merge 를 설치해주세요.

webpack.common.conf.js

webpack.common.conf.js 에서는 엔트리, 아웃풋, 플러그인과 같이 실행 모드에 관계 없이 항상 들어가야 하는 코드를 넣겠습니다.

const path = require("path");

module.exports = {
    entry : "./src/index.js", //webpack 번들링의 시작점
    output: { // 번들링 결과물을 내보내는 방법과 관련된 옵션
        path: path.resolve(__dirname,'..','dist'),
        filename: "index.js",
    },
    module: { // 모듈 관련 설정
        rules: [ // 모듈에 대한 규칙
            {
                test: /\.html$/, //어떤 파일이 transform 될지
                use: [ // 어떤 로더가 transform 에 사용 될지
                    {
                      //...
                    }
                ]
            }
        ]
    }
}
  • 여기서 path.resolve() 의 매개변수로 __dirname,..,dist 세 문자열을 전달해주었는데요, 현재 파일(./conf/webpack.common.conf.js)이 위치한 폴더를 기준으로 루트경로까지의 절대 경로를 반환합니다. 따라서 conf 폴더 -> working directory 폴더 -> dist 폴더 로 경로를 지정해주었습니다.

  • 저는 SCSS를 사용할 것인데요, 웹팩이 SCSS 로 작성된 파일을 읽을 수 있도록
    npm i -D css-loader style-loader mini-css-extract-plugin sass-loader
    로 관련 로더를 설치 후, 설정해주었습니다.
    - css-loader
    - style-loader : CSS를 DOM에 삽입합니다.
    - mini-css-extract-plugin : CSS 파일을 별도 파일로 추출(extract) 합니다. CSS 코드가 포함된 JS 파일 별로 CSS 파일을 생성합니다.
    - sass-loader : SASS/SCSS 파일을 CSS로 변환해줍니다.

webpack.development.conf.js

webpack.development.conf.js 에서는 개발자 도구나 webpack dev server 설정을 하도록 하겠습니다.

const { merge } = require('webpack-merge');
const common = require('./webpack.common.conf.js');
module.exports = merge(common, {
    mode: 'development',
    devServer: {
        port:9000,
        hot: true, //HMR 기능 활성화
        //compress : 모든 항목에 대해 gzip 압축 사용 
        //contentBase: 정적 파일 제공하려는 경우 필요
        open:true
    }
})

webpack-merge 가 제공하는 merge API 를 사용하여 webpack.common.conf.js의 설정과 webpack.development.conf.js 설정을 합칠 수 있습니다.

const { merge } = require('webpack-merge');

// Keys matching to the right take precedence:
const output = merge(
  { fruit: "apple", color: "red" },
  { fruit: "strawberries" }
);
console.log(output);
// { color: "red", fruit: "strawberries"}

webpack.production.conf.js

const { merge } = require('webpack-merge');
const common = require('./webpack.common.conf.js');
module.exports = merge(common, {
    mode: 'production',
})

NPM script 등록

//pakage.json
"scripts": {
  "serve": "webpack serve --config ./conf/webpack.development.conf.js",
  "build": "webpack --config ./conf/webpack.common.conf.js"
}

--config 플래그를 사용해 특정 상황에서 특정 설정 파일을 사용할 수 있도록 합니다!

HTML 빌드

이제 HTML 파일을 빌드해보겠습니다! public 폴더 안에 index.html 파일을 생성해주세요. Webpack loader 를 통해 은 자바스크립트가 아닌 파일도 모듈로 관리할 수 있습니다. html-loader 를 설치해, HTML 파일을 웹팩이 이해할 수 있도록 하겠습니다.

<!--public/index.html-->
<!DOCTYPE html>
<html lang="kr">
<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>

React, Typescript 설치

npm i -D react react-dom typescript @types/react @types/react-dom

참고

profile
프론트가 좋아요

0개의 댓글