웹팩이란 최신 프런트엔드 프레임워크에서 가장 많이 사용되는 모듈 번들러(Module Bundler)이다. 모듈 번들러란 웹 애플리케이션을 구성하는 자원(HTML, CSS, Javscript, Images 등)을 모두 각각의 모듈로 보고 이를 조합해서 병합된 하나의 결과물을 만드는 도구를 의미한다.
https://joshua1988.github.io/webpack-guide/webpack/what-is-webpack.html
📌 모듈은 각 리소스 파일이고, 번들은 웹팩 실행 후에 나오는 결과 파일이다.
리액트는 SPA이기 때문에 한페이지에 자바스크립트 파일이 너무 많다. 따라서 웹팩을 이용해 번들링 하여 하나의 파일로 자바스크립트 파일을 관리 한다.
- 백팩(backpack)의 뜻은 물건을 넣어서 등에 질 수 있도록 헝겊이나 가죽 따위로 만든 주머니 이다.
- 웹팩은 웹에서 이용하기 위해 모듈을 담아서 하나로 만드는 번들러라고 생각하면 된다.
npm install webpack webpack-cli
📌 babel 처럼 webpack은 webpack을 사용하기 위한 필수 패키지이고, cli는 커맨드 라인에서 사용하기 위한 패키지 이다
src/util.js
export function sayHello(name) {
console.log("hello", name);
}
src/index.js
import { sayHello } from "./util";
function myFunc() {
sayHello("mike");
console.log("myFunc");
}
myFunc();
npx webpack
로 실행하면 dist 폴더가 생기면서 아래와 같은 파일이 생긴다.
dist/main.js
(()=>{"use strict";console.log("hello","mike"),console.log("myFunc")})();
webpack 설정은 프로젝트 루트의 webpack.config.js
로 한다.
webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
mode: "production",
optimization: { minimizer: [] },
};
실행해보면 아래처럼 나온다
dist/main.js
/******/ (() => { // webpackBootstrap
/******/ "use strict";
var __webpack_exports__ = {};
;// CONCATENATED MODULE: ./src/util.js
function sayHello(name) {
console.log("hello", name);
}
;// CONCATENATED MODULE: ./src/index.js
function myFunc() {
sayHello("mike");
console.log("myFunc");
}
myFunc();
/******/ })()
;
로더는 모듈을 입력으로 받아서 원하는 형태로 변환한 후 새로운 모듈을 출력해 주는 함수이다.
우리가 jsx 문법으로 코드를 작성하고 웹팩으로 번들링 하려 하면 웹팩이 jsx 문법을 이해하지 못한다.
따라서 바벨로더로 jsx 문법을 변환한 후 번들링 해야한다
npm install babel-loader @babel/core @babel/preset-react react react-dom
바벨과 react를 사용하기 위해 패키지를 설치해 준다.
src/index.js
import React from 'react';
import ReactDOM from "react-dom";
import "./App.css";
function App() {
return (
<div className="container">
<h3 className="title">ssdfsdfs</h3>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root');
babel.config.js
const presets = ["@babel/preset-react"];
module.exports = { presets };
preset-react를 사용하도록 설정해주고 jsx문법으로 코드를 작성한다.
webpack.config.js
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-react"],
},
},
},
],
},
mode: "production",
};
아래의 파일을 만들어서 웹팩 실행후 확인해 보면 화면이 잘나오는것을 확인 할 수 있다.
dist/index.html
<html>
<body>
<div id="root">
<script src="./main.js"></script>
</body>
</html>
css, image, json, text등을 로더로 처리할 수 있다.
// css
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
// image
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 8192,
},
},
],
},
// text
{
test: /\.txt$/,
use: "raw-loader",
},
위 코드처럼 로더들을 설치한 후에 설정 파일에 넣으면 된다.
src/index.js
import React from 'react';
import ReactDOM from "react-dom";
function App() {
return (
<div className="container">
<h3 className="title">learn webpack</h3>
</div>
);
}
ReactDOM.render(<App />, document.getElementById('root');
npm install clean-webpack-plugin html-webpack-plugin
webpack.config.js
const path = require("path");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
entry: "./src/index.js",
output: {
filename: "[name].[chunkhash].js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-react"],
},
},
},
],
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
template: "./template/index.html",
}),
],
mode: "production",
};
template/index.html
<html>
<head>
<title>웹팩 플러그인</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
이건 설치할 필요는 없다
const webpack = require("webpack");
new webpack.DefinePlugin({
APP_VERSION: '"1.2.3"',
TEN: "10",
}),
아까 플러그인 사용했던것 처럼 위 코드를 넣고 번들링할 파일에서
`${APP_VERSION}`
`${TEN}`
위 처럼 사용하면 설정한 대로 번들링된다.
cra로 리액트 코드를 짜다보면 import React 안해도 잘 돌아간다
그게 이것때문이라는 거를 이번에 알게 되었다.
new webpack.ProvidePlugin({
React: "react",
}),
위 코드가 웹팩 설정파일에 있어서 가능한 거였다.
❗️ 역시 cra가 편하긴 하다
참고: 실전 리액트 프로그래밍