[React.js] Webpack Setting
ํ๊ทธ: reactjs · webpack · babel-loader · html-webpack-plugin · babel/core · babel/preset-env · babel/preset-react · react-refresh-webpack-plugin
- 1. ํด๋ ๊ตฌ์กฐ
- 2. ํจํค์ง ์์ฑ
- 3. ํจํค์ง ์ค์น
- ๋ฆฌ์กํธ
- ์นํฉ
- ์นํฉ ํ๋ฌ๊ทธ์ธ
- ๋ฐ๋ฒจ
- 3. ์นํฉ ์ค์
- devServer HMR & ํซ ๋ฆฌ๋ก๋ฉ
- 4. package.json
- 5. ์ฝ๋์์ฑ
- public/index.html
- src/index.js
- src/app.js
- src/index.css
- ๊ฐ๋ฐ์๋ฒ ์คํ
1. ํด๋ ๊ตฌ์กฐ
//React18
โโ dist
โโ package-lock.json
โโ package.json
โโ public
โ โโ index.html
โโ src
โ โโ App.js
โ โโ index.js
โ โโ index.css
โโ webpack.config.js
CRA ๋ช ๋ น์ด๋ก ์์ฑํ ๊ฒ ์ฒ๋ผ ์์ ๊ฐ์ด ๊ตฌ์ฑํ์ต๋๋ค.ย ๊ฐ ํด๋๋ณ ์ฐ์์๋ ์๋์ ๊ฐ์ต๋๋ค.
- public: HTML ํ ํ๋ฆฟ๊ณผ ์ด๋ฏธ์ง ํ์ผ ๋ฑ ์ ๋๊ฒฝ๋ก๋ก ์ฐ์ด๋ ํ์ผ์ด ์์นํ๋ ์ฅ์
- src: ๊ธฐ๋ณธ์ ์ผ๋ก ์์ฑํ๋ ์์ค์ฝ๋๊ฐ ์์นํ๋ ์ฅ์
- dist: ์นํฉ์ด ๋ฒ๋ค๋ง๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๋ ์ฅ์
์ด๋ ๊ฒ ์์ฑํ ๊ตฌ์กฐ๋๋ก npm ํจํค์ง ๋งค๋์ ๋ฅผ ํตํด ํ์ํ ํจํค์ง๋ค์ ์ค์นํ๊ณ ย ์นํฉ ์ค์ ์ ์งํํ๋๋ก ํ๊ฒ ์ต๋๋ค. ๋จผ์ ๋ชจ๋ ๋ฒ๋ค๋ฌ๋ ์นํฉ์ ๋ํ ์ง์์ด ์๋ ๋ถ๋ค์ ์๋ ํฌ์คํ ์ ๋จผ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
2. ํจํค์ง ์์ฑ
npm init
ํฐ๋ฏธ๋์ ํตํด npm ๋ช ๋ น์ด๋ก ํจํค์ง๋ฅผ ์์ฑํด์ค๋๋ค. ์์ฑ์ ๋ฐ ํ๋ก์ ํธ ์ด๋ฆ์ ๊ฐ๋ณ ์ค์ ํด์ค๋๋ค.
3. ํจํค์ง ์ค์น
๋ฆฌ์กํธ
yarn add react react-dom
์นํฉ
yarn add webpack webpack-cli webpack-dev-server
์นํฉ๊ณผ ํ๋ฌ๊ทธ์ธ์ ๊ฐ๋ฐํ๊ฒฝ์์๋ง ํ์ํ๋ฏ๋ก ์ค์น ์ โ-Dโ ๋๋ โโsave-devโ ์ต์ ์ ์ถ๊ฐํด์ค๋๋ค.
์นํฉ ํ๋ฌ๊ทธ์ธ
yarn add babel-loader html-webpack-plugin clean-webpack-plugin css-loader style-loader cross-env dotenv dotenv-webpack
- babel-loader: ์นํฉ์์ ๋ฐ๋ฒจ์ ์ฌ์ฉํ ์ ์๋๋ก ์ฒ๋ฆฌ
- CleanWebpackPlugin: ์ด์ ์ ๋ฒ๋ค๋ ํ์ผ ์๋ ์ญ์
- HtmlWebpackPlugin: HTML ํ ํ๋ฆฟ ์ค์
- css-loader/style-loader: CSS ๊ด๋ จ ํ์ผ ์ฒ๋ฆฌ
๋ฐ๋ฒจ
yarn add @babel/core @babel/preset-env @babel/preset-react
3. ์นํฉ ์ค์
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const ESLintPlugin = require("eslint-webpack-plugin"); // eslint ์ฌ์ฉํ ๊ฒฝ์ฐ
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
// const isDevelopment = process.env.NODE_ENV !== "production";
// const envPath = `./.env.${isDevelopment ? "development" : "production"}`;
// dotenv.config({
// path: envPath,
// });
const config = {
name: "React18-webpack-babel-setting", // ์ค์ ์ด๋ฆ
mode: "development", // production, development // ์ค์ ๋ชจ๋
devtool: "eval",
entry: {
app: "./src/index.js",
},
resolve: {
extensions: [".js", ".jsx"],
},
module: {
rules: [
{
// ๋ฆฌ์กํธ ๋ฐ๋ฒจ ์ค์
test: /\.js/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react"],
},
},
},
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./public/index.html", // ํ
ํ๋ฆฟ ์ค์
minify: true, // ์์ถ ์ค์
}),
new webpack.ProvidePlugin({
// ๋ฆฌ์กํธ ์๋ ๋ก๋
React: "react",
}),
new ESLintPlugin(),
new ReactRefreshWebpackPlugin(),
],
output: {
path: path.resolve(__dirname, "dist"),
filename: "app.js",
publicPath: "/",
},
devServer: {
// ๊ฐ๋ฐ ์๋ฒ ์ค์
port: 3000, // ํฌํธ ์ค์
hot: true, // ํซ ๋ชจ๋ ๊ต์ฒด(HMR) ํ์ฑํ
compress: true, // ์์ถ ์ ๋ฌด
open: true, // ๊ธฐ๋ณธ ๋ธ๋ผ์ฐ์ ์์ ์คํ
historyApiFallback: true, // connect-history-api-fallback error ๋ฐฉ์ง
},
};
module.exports = config;
๋ณ๊ฒฝ ํ์คํ ๋ฆฌ
+์ถ๊ฐ)
..
plugins: [
..
new webpack.ProvidePlugin({
"React": "react",
})
..
]
..
์ปดํฌ๋ํธ๋ง๋ค import React from โreactโ ์ ์ธ์ ๊ผญ ํด์ค์ผ ํ๋๋ฐ์. ProviderPlugin์ ์ฌ์ฉํ๋ฉดย ๋ฆฌ์กํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํ ๊ณณ์๋ ์นํฉ์ด ์์์ ๋ฃ์ด์ค๋๋ค. ๋ฌผ๋ก CRA๋ฅผ ํตํด ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ ๋์ผํ์ง๋ง์ :)
moment ๊ฐ์ด ์์ฃผ ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ ๊ฒฝ์ฐ ์ถ๊ฐํด ๋์ผ๋ฉด ์๋จ์ ์ ์ธ ์์ด ์ฌ์ฉํ ์ ์์ด ํธ๋ฆฌํฉ๋๋ค.
devServer HMR & ํซ ๋ฆฌ๋ก๋ฉ
yarn add @pmmmwh/react-refresh-webpack-plugin
๊ธฐ์กด ๋ฆฌ๋ก๋ฉ์ ๋ณ๊ฒฝ์ฌํญ์ด ๋ฐ์ํ๋ฉด ์ ์ฒด๊ฐ ์๋ก๊ณ ์นจ ๋๋๋ฐ, ๋ณ๊ฒฝ๋ ๋ถ๋ถ๋ง ๋น ๋ฅด๊ฒ ๋ฐ๊ฟ์ฃผ๋ย react-refresh-webpack-plugin์ ์ ์ฉํฉ๋๋ค. ํด๋น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ค์นํ๊ณ ํ๋ฌ๊ทธ์ธ์ ์ถ๊ฐํด์ค๋๋ค.
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
..
plugins: [
...
new webpack.HotModuleReplacementPlugin(),
new ReactRefreshWebpackPlugin()
...
],
devServer: {// ๊ฐ๋ฐ ์๋ฒ ์ค์ port: 3000,// ํฌํธ ์ค์ hot: true,// ํซ ๋ชจ๋ ๊ต์ฒด(HMR) ํ์ฑํcompress: true,// ์์ถ ์ ๋ฌดopen: true,// ๊ธฐ๋ณธ ๋ธ๋ผ์ฐ์ ์์ ์คํhistoryApiFallback: true,// connect-history-api-fallback error ๋ฐฉ์ง
}
..
devServer์ ๊ด๋ จ๋ ์ค์ ์ด ์์ฒญ ๋ง์ ์ธ๋ถ ์ค์ ๋ด์ฉ์ ์๋์์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
4. package.json
ํ์ํ ํจํค์ง ๋ฐ ์นํฉ ์ค์ ์ด ๋๋ฌ์ต๋๋ค. package.json ํ์ผ์ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
// package.json"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "cross-env webpack serve --env development",
"build": "cross-env NODE_ENV=production webpack"
}
- npm run dev: ์นํฉ ๋ฐ๋ธ ์๋ฒ ์คํ ๋ช ๋ น์ด
- npm run build: ์นํฉ ๋ฒ๋ค๋ง ๋ช ๋ น์ด
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ๋ฆฌ์กํธ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ ํ๊ฒฝ์ ๋ง๋ค์ด๋จ์ต๋๋ค. index.html -> index.js -> app.js ์์ผ๋ก ์ฝ๋๋ฅผ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
5. ์ฝ๋์์ฑ
public/index.html
<!DOCTYPE html>
<html lang="ko">
<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>Hello, React18!</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
๋น์ฃผ์ผ ์คํ๋์ค์์ ! -> tab ์๋ฐ ๊ธฐ๋ฅ์ผ๋ก ๋ง๋ค์ด์ค๋๋ค. <body /> ํ๊ทธ์๋ <div /> ํ๊ทธ ํ๋๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
src/index.js
import ReactDom from "react-dom/client";
import App from "./App";
import "./index.css";
const root = document.getElementById("macjjuni");
ReactDom.createRoot(root).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// ๋ฆฌ์กํธ 18 ์ด์ ๋ฒ์ // ReactDom.render(// <App/>,// document.getElementById("root")// )
๋ฆฌ์กํธ 18 ์ด์ ๋ฒ์ ์์๋ ReactDom.render ํจ์๋ฅผ ์ฌ์ฉํ์ผ๋ 18 ์ดํ ReactDom.createRoot().render ํจ์๋ก ๋ณ๊ฒฝ๋์์ต๋๋ค.
์ฌ๊ธฐ์ ๋ฆฌ์กํธ ์์ฒด๋ฅผ ์ ์ธํ์ง ์์๋๋ฐ, ๊ทธ ์ด์ ๋ ์นํฉ์์ ์ค์ ํด์คฌ๊ธฐ ๋๋ฌธ์ ๋๋ค.
src/app.js
export default function App() {
return (
<>
<div className="wrap">
<h1 className="title">Hello, React18!</h1>
</div>
</>
);
}
src/index.css
@charset "utf8";
* {
box-sizing: border-box;
margin: 0 auto;
}
.wrap {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
width: 100vw;
height: 100vh;
}
.title {
font-size: 50px;
font-weight: bold;
color: skyblue;
}
์ด์ ์นํฉ ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์คํํด์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
๊ฐ๋ฐ์๋ฒ ์คํ
yarn dev