Webpack으로 React 앱 빌드하기

우선 webpack.config.js 파일을 작성해 줌.

module.exports = {
    mode: 'production',
    entry: './src/index.js',
    output: {
        path: path.resolve(__dirname, './dist'),
        filename: 'app.bundle.js',
    }
}

React 앱을 빌드하기 위해서 필요한 로더에는 JSX 표현을 웹 브라우저에서 읽을 수 있는 표현으로 바꿔주는 babel-loader, Javascript 파일에서 CSS 파일을 불러오기 위한 style-loader, css-loader, HTML도 같이 컴파일해서 빌드해주는 html-webpack-plugin가 있음.

 

 

1. style-loader, css-loader 설정하기

npm install -D css-loader style-loader

터미널에서 css-loader, style-loader를 설치해줌.

 

module: {
    rules: [
        {
            test: /\.css$/,
            use: ["style-loader", "css-loader"],
            exclude: /node_modules/,
        },
    ],
},

use 속성은 배열 마지막 요소부터 오른쪽에서 왼쪽 순으로 적용되고, 먼저 css-loader가 적용된 후 styled-loader가 적용되어야 하기 때문에 위와 같이 설정을 해줌.

 

 

 

3. babel-loader 설정하기 #

npm install -D babel-loader @babel/core @babel/preset-react

터미널에서 babel-loader, @babel/preset-react를 설치해줌.

 

// babel-loader 로더 설정
module: {
    rules: [
        {
            test: /\.m?js$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: ["@babel/preset-react"]
                }
            }
        }
    ],
}

Webpack 컴파일 결과

이대로 설정을 하고 빌드를 했을 때 React is not defined라는 오류가 뜨는데 왜 그럴까?

const profile = (
    <div>
        <img src="avatar.png" className="profile" />
        <h3>{[user.firstName, user.lastName].join(" ")}</h3>
    </div>
);

babel-loader가 React Classic Runtime 모드로 작동(기본값)할 때, 위 코드는 아래처럼 컴파일됨. #

const profile = React.createElement(
    "div",
    null,
    React.createElement("img", { src: "avatar.png", className: "profile" }),
    React.createElement("h3", null, [user.firstName, user.lastName].join(" "))
);

일반적으로 React 앱을 작성하면서 index.js 파일 외에서는 주로 import { useState, useEffect } from "react" 를 사용하지, import React from "react" 를 사용하는 일은 많지 않음. React 앱을 작성할 때는 문제가 되지 않지만 bable로 컴파일하게 되면 JSX 표현은 React.createElement()를 이용해 표현되기 때문에 빌드 결과를 열어보면 React is not defined 라는 오류를 보게 됨.

 

따라서, 이 오류를 해결하기 위해서는 ① babel-loader를 Automatic Runtime 모드로 설정하거나,

module: {
    rules: [
        {
            test: /\.m?js$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: [["@babel/preset-react", { runtime: "automatic" }]]  // 런타임 모드 변경
                }
            }
        }
    ],
}

② 모든 React 컴포넌트 파일에 import React from "react" 를 작성해주는 방법도 있지만, 이 방법은 추천하지 않음.

 

 

 

 

 

 

 

 

[참고]

Uncaught ReferenceError: React is not defined

그 많던 import React from ‘react’는 어디로 갔을까