지금까지 리액트 프로젝트를 생성할 때 CRA로 줄곧 진행을 했었는데, 이번에는 CRA없이 직접 웹팩과 바벨설정을 하면서 리액트 프로젝트 내부에서 어떤 일이 발생하는지 이해하고자 진행을 해봤습니다.
react-webpack5
라는 이름으로 폴더를 생성했습니다.npm init -y
폴더안에 아래와 같은package.json
파일이 생성 될 것입니다.
{
"name": "react-webpack5",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
npm i react react-dom
package.json
파일의 디펜더시 항목에 추가됩니다. "dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
}
npm i -D @babel/core @babel/preset-env @babel/preset-react babel-loader file-loader css-loader style-loader webpack webpack-cli html-webpack-plugin webpack-dev-server
package.json
파일을 확인해보면 devDependencies에 아래와 같이 추가됐음을 확인 할 수 있습니다. "devDependencies": {
"@babel/core": "^7.15.5",
"@babel/preset-env": "^7.15.4",
"@babel/preset-react": "^7.14.5",
"babel-loader": "^8.2.2",
"css-loader": "^6.2.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.2",
"style-loader": "^3.2.1",
"webpack": "^5.52.0",
"webpack-cli": "^4.8.0"
"webpack-dev-server": "^4.1.1"
}
.babelrc
파일을 생성해 줍니다. jsx에서 일반 js로 리액트 코드를 변환하기 위해 필요합니다.//.babelrc
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
현재 파일 구조는 다음과 같습니다.
webpack.config.js
파일을 생성합니다. 이 웹팩 파일은 기본적으로 브라우저가 아닌 노드 환경에서 실행됩니다. 따라서 여기에 바닐라 js 코드를 작성할 수 있습니다.파일에는 아래의 코드를 넣어주세요.
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
output: {
path: path.join(__dirname, "/dist"),
filename: "index.bundle.js",
},
devServer: {
port: 3000,
liveReload: true,
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /nodeModules/,
use: {
loader: "babel-loader",
},
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
plugins: [new HtmlWebpackPlugin({ template: "./public/index.html" })],
};
output
에서는 파일이 번들되면 어디로 보내야 하는지 언급합니다.path
에는 번들 파일이 저장될 디렉토리 이름이 지정되어 있습니다. 폴더 이름을 dist
라고 지었는데, 이것은 일반적인 관행입니다.filename
은 웹팩이 실행된 후 생성되는 새로운 번들 파일에 대해 설정한 이름입니다(기본적으로 모든 js 코드를 하나의 파일로 묶습니다).devServer
어플리케이션을 구축하는 데 훨씬 많은 시간이 걸리는 프로덕션 모드와 반대되게 어플리케이션을 신속하게 개발하기 위해 사용됩니다.port
를 사용하면 원하는 포트 번호를 설정할 수 있습니다. 저는 3000으로 설정했습니다.liveReload
는 파일에 변경 사항이 있을 때 바로 반영해서 출력해 줍니다.module
은 파일 번들링 규칙을 지정하는 옵션입니다.test
는 특정 로더의 대상이 되어야 하는 파일의 확장자를 언급하는 경우입니다. 모든 .js
또는 .jsx
파일은 바벨 로더에 의해 번들되어야 합니다.exclude
번들러가 무시해야 하는 파일을 지정합니다.css
파일도 마찬가지입니다.use :['style-loader', 'css-loader']
배열은 정확한 순서로 작성되어야 합니다.css-loader
를 실행합니다.style-loader
를 실행합니다.plugins
마지막으로 우리는 HtmlWebpackPlugin이라고 불리는 플러그인을 추가하는데, 이것은 웹팩이 html 파일 템플릿을 알 수 있도록 합니다.복잡한 부분이 완료되었으니 이제 리액트 파일을 추가해주도록합시다.
public
폴더와 src
폴더를 생성해주고, 각 폴더에 아래와 같이 파일을 추가해주세요.public
-index.html
src
-index.js
-App.js
-App.css
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Webpack5 App</title>
</head>
<body>
<div id="app"></div>
<script src="index.bundle.js"></script>
</body>
</html>
import React from "react"
import ReactDom from "react-dom"
import App from "./App"
import "./App.css"
ReactDom.render(<App />, document.getElementById('app'))
간단한 내용을 추가합니다.
import React from "react"
function App() {
return (<div>
<h2>Welcome to React App</h2>
<h3>Date : {new Date().toDateString()}</h3>
</div>)
}
export default App
h2{
color: teal
}
이제 스크립트 실행을 위해 package.json
파일을 수정해야합니다.
"scripts": {
"serve": "webpack serve --mode development",
"build": "webpack --mode production"
}
npm run serve
개발 모드에서는 아래와 같이 번들된 코드가 정렬되어 나옵니다.
localhost:3000
npm run build
이로써 create-react-app없이 Webpack5환경에서 React 프로젝트를 시작할 수 있게되었습니다.
간단하지는 않지만 웹팩과 바벨에 대한 이해도도 올라가고 정말 필요한 옵션들만 골라서 추가해줄 수 있어서 추후 최적화하기도 좋을 것 같네요. 읽어주셔서 감사합니다:)