Menu

메모용 개발 블로그

전체보기 > Develop > React >

React + Webpack + TypeScript 세팅

2024-06-25 12:24:10

환경

OS: Windows 11, AMD64

Node.js: v20.14.0 (lts)

Package Install

npm i react react-dom
npm i -D webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader style-loader css-loader @babel/core @babel/preset-react @babel/preset-typescript prettier typescript @types/react-dom

Prettier

소스코드의 일관된 컨벤션을 위함이므로 구성 설정과 무관

저장 시 자동 정렬은 각 에디터마다 설정을 해주어야 함.

소스코드에 DOM이 들어가는 구조상 들여쓰기가 많아서 2space를 권장하지만 싫다면 아래로 설정

/.prettierrc

{
    "tabWidth": 4
}

HTML Entrypoint

진입할 html 파일 생성한다. 기준이 될 div만 자유롭게 작성한다.

대부분은 root id를 찾아서 쓴다.

/index.html

<!doctype html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>

Webpack

각 환경별로 설정파일을 분할한다.

/webpack.common.js

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

module.exports = {
    entry: {
        main: "./src/index.tsx",
    },
    output: {
        path: path.resolve(__dirname, "./dist"),
    },
    resolve: {
        extensions: [".ts", ".tsx", ".js"],
    },
    module: {
        rules: [
            {
                test: /\.(tsx|ts)?$/,
                exclude: /node_modules/,
                loader: "babel-loader",
                options: {
                    presets: [
                        ["@babel/preset-react", { runtime: "automatic" }],
                        "@babel/preset-typescript",
                    ],
                },
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"],
            },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, "./src/index.html"),
        }),
    ],
    optimization: {
        splitChunks: {
            chunks: "all",
        },
    },
};

webpack.config.dev.js

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");

module.exports = merge(common, {
    mode: "development",
    devServer: {
        hot: true,
        liveReload: true,
    },
});

webpack.config.prod.js

const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");

module.exports = merge(common, {
    mode: "production",
});

package.json에 다음 항목 수정

"scripts": {
    "build": "webpack --config webpack.config.prod.js",
    "dev": "webpack serve --config webpack.config.dev.js"
},

React Entrypoint

리액트 진입점 파일

html에서 기준 DOM을 찾아서 그려주거나 각종 설정용 컴포넌트 위치

개발 시 div 부분은<App /> 같이 앱의 최상위 컴포넌트를 넣음.

/src/index.tsx

import { createRoot } from "react-dom/client";

const rootDOM = document.getElementById("root");
const root = createRoot(rootDOM);

root.render(<div></div>);