0. Webpack?
웹팩은 모듈 번들러이다.
여기서 모듈은 각 리소스 파일을 말하고, 번들은 Webpack 실행 후 나오는 결과 파일이다.
하나의 번들 파일은 여러 모듈로 만들어진다.
즉, Webpack을 이용하면 우리가 제작한 여러 가지 리소스(js, css, ... )를 사용자에게 전달하기 좋은
형태로 만들 수 있다.
필요 이유?
초기 웹 페이지는 페이지가 바뀔 때마다 새로운 HTML을 요청해서 화면을 그리는 방식이었다.
자바스크립트는 돔을 간단하게 조작하는 역할만 했고, Ajax가 유행했을 때는 자바스크립트의
비중이 더 커졌지만 페이지당 자바스크립트 파일 몇 개면 충분했다.
하지만 SPA가 나오면서 하나의 HTML에 수십, 수백 개의 자바스크립트 파일을 포함하기 때문에
기존 방식이 통하지 않았다.
<html>
<head>
<script src="javascript_file_1.js"/>
<script src="javascript_file_2.js"/>
<script src="javascript_file_3.js"/>
// ....
<script src="javascript_file_1.js"/>
</head>
</html>
일반적인 방식으론 계속 늘어나는 자바스크립트 파일을 관리하기 힘들다.
또한 실행 순서도 신경 써야 하고, 기존 생성된 전역 변수를 덮어쓰는 위험도 존재한다.
// index.html
<html>
<head>
<script src="https://unpkg.com/lodash@ ... "></script>
</head>
<body>
<script src="./index.js"></script>
</body>
</html>
// index.js
const element = document.createElement('div');
element.innerHTML = _.join(['hello', 'world'],'');
document.body.appendChild(element);
웹팩을 사용하지 않고 script 태그를 사용해서 외부 모듈을 가지고 오는 코드이다.
이 방식에 몇 가지 문제점이 있는데,
1. 만약 가지고 오는 주솟값에 오타가 있다면 외부 모듈을 가지고 오지 못한다.
2. 주솟값을 제대로 입력했다고 하더라도 unpkg 사이트에 장애가 있는 경우 실패한다.
3. 코드가 필요 없어진 경우 자바스크립트 코드에서 해당 부분을 제거하여도 script 태그를 지우는 것을 까먹으면
불필요한 리소스의 다운로드가 발생해 초기 렌더링이 느려질 수 있다.
하지만 웹팩을 사용하면 문제를 해결할 수 있다.
1. Webpack 실행하기
npm install webpack webpack-cli
webpack-cli를 사용하면 CLI에서도 Webpack을 실행할 수 있다.
// util.js
export const sayHello = (name) => {
console.log(name);
};
// index.js
import { sayHello } from "./util";
const myFunc = () => {
sayHello("Ing-yo");
console.log("myFunc");
};
myFunc();
예시 코드를 작성하고 테스트를 진행하면 dist 폴더가 만들어지고 그 밑에 main.js 번들 파일이 생성된다.
npx webpack
index.js 모듈과 util.js 모듈이 main.js 번들 파일로 합쳐졌다.
별다른 설정 없이 Webpack을 실행하면 ./src/index.js 모듈을 입력 받아 ./dist/main.js 번들 파일을 만든다.
설정 파일 이용하기
const path = require("path");
module.exports = {
entry: "./src/index.js", --- 1
output: { --- 2
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
mode: "production", --- 3
optimization: { minimizer: [] }, --- 4
};
1. index.js 파일을 입력 파일로 사용한다. 즉, 시작 파일이 index.js라는 것이다.
2. dist 폴더 밑에 main.js 번들 파일을 생성한다.
3. 프로덕션 모드로 설정하면 자바스크립트 코드 압축을 포함한 여러 가지 최적화 기능이 기본적으로 들어간다.
4. 번들 파일의 내용을 쉽게 확인하기 위해 압축하지 않도록 설정했다.
2. 로더 사용하기
로더는 모듈을 입력받아서 원하는 형태로 변환 후 새로운 모듈을 출력해주는 함수이다.
자바스크립트 파일뿐만 아니라 이미지, CSS, CSV 파일 등 모든 파일은 모듈이 될 수 있다.
npm install webpack webpack-cli
기본적인 패키지를 우선 설치한다.
자바스크립트 파일 처리하기
npm install babel-loader @babel/core @babel/preset-react react react-dom
import React from "react";
import ReactDOM from "react-dom";
const App = () => {
return (
<div>
<h3>Webpack example</h3>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));
자바스크립트 코드에서 JSX 문법으로 작성된 리액트 코드를 처리하기 위해 필요한 패키지들과
예시로 사용할 React 코드이다.
const presets = ["@babel/preset-react"];
module.exports = { presets };
Babel을 사용하기 위해서 babel.config.js을 만들고 @babel/preset-react 프리셋을 사용해 JSX 문법을 변환할 것이다.
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: "babel-loader",
},
],
},
mode: "production",
};
js 확장자를 갖는 모듈은 babel-loader가 처리하도록 설정하였다.
만약 babel-loader를 설정하지 않고 웹팩을 실행하면 웹팩이 JSX 문법을 이해하지 못하여 에러가 발생한다.
CSS 파일 처리하기
이제 CSS 파일을 처리하는 로더를 작성하자
npm install css-loader style-loader
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
...
{
test: /\.css$/,
use: ["style-loader", "css-loader"],
},
],
},
mode: "production",
};
css-loader를 통해서 생성된 css 데이터를 style-loader가 style 태그로 만들어서 HTML head에 삽입한다.
기타 파일 처리하기
이번엔 PNG, TXT, JSON 파일 등을 처리해보자
const path = require("path");
module.exports = {
entry: "./src/index.js",
output: {
filename: "main.js",
path: path.resolve(__dirname, "dist"),
},
module: {
rules: [
...
{
test: /\.(png|jpg|gif)$/,
use: "file-loader",
},
{
test: /\.txt$/,
use: "raw-loader",
},
],
},
mode: "production",
};
실행 후 dist 폴더에 생성된 이미지 파일의 이름엔 해시값이 포함되어 있다.
해시값은 이미지 파일을 수정하는 경우에만 변경되기 때문에 사용자에게 전달된 이미지 파일은 브라우저의 캐싱
효과를 최대한 활용할 수 있다.
이미지 파일의 요청 횟수 줄이기
이미지 파일을 번들 파일에 포함시키면 브라우저의 파일 요청 횟수를 줄일 수 있다.
이때 번들 파일 크기가 너무 커지면 자바스크립트가 늦게 실행되므로 작은 이미지 파일만 포함시키는 것이 좋다.
npm install url-loader
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: "url-loader",
options: {
limit: 8192,
},
},
],
},
url-loader는 파일 크기가 limit보다 작은 경우 번들 파일에 파일의 내용을 포함시킨다.
만약 파일 크기가 이 값보다 큰 경우 다른 로더가 처리할 수 있도록 fallback 옵션을 제공한다. 하지만 입력하지 않으면
기본적으로 flie-loader가 처리하게 되어있다.
3. 깃허브
https://github.com/SeoJaeWan/webpack-init
https://github.com/SeoJaeWan/webpack-loader
'React > 실험실' 카테고리의 다른 글
[React] Webpack - 심화 (3) | 2022.04.28 |
---|---|
[React] Webpack - Plugin 사용 (0) | 2022.04.18 |
[React] Babel과 Polyfill (0) | 2022.04.06 |
[React] Babel - 깊은 설정 (0) | 2022.04.05 |
[React] Babel (2) | 2022.04.04 |