Webpack
웹팩은 자바스크립트 모듈 번들러로 js
파일을 포함한 asset(image, font, style 등)을 컴파일, 번들링한다.
번들러
모듈 번들러는 여러 개의 자바스크립트 파일을 하나의 파일로 묶어서 한 번의 요청을 통해 가지고 올 수 있게 하는 도구이다.
프로젝트 생성
$ mkdir webpack-test
$ cd webpack-test
$ npm init
$ npm installl --save-dev webpack webpack-cli
.
├── src/
│ └── index.js
│ └── js/
│ └── sayHello.js
│ └── name.js
├── package-lock.json
└── package.json
// src/index.js
import sayHello from "./js/sayHello";
import name from "./js/name";
console.log(sayHello());
console.log(name.isValid("Rich"));
// src/js/sayHello.js
const sayHello = () => {
return "Hello I am Webpack";
};
export default sayHello;
// src/js/name.js
import * as _ from "lodash"; // loadash 외부 라이브러리를 설치해줬다. npm i loadash
let minLen = 2;
const isValid = () => {
return _.trim(name).length >= minLen;
};
export default { isValid };
$ npx webpack
모드를 설정하지 않고 실행하면, 모드를 설정하라는 경고 문구가 나온다.
$ npx webpack --mode=development # 개발 모드로 모듈 번들링
번들링이 성공하면 아래와 같은 문구가 나온다.
# Webpack 번들링 결과 출력
asset main.js 8.24 KiB [emitted] (name: main)
asset index.html 271 bytes [compared for emit]
runtime modules 695 bytes 3 modules
cacheable modules 2.89 KiB
./src/index.js 155 bytes [built] [code generated]
./src/js/sayHello.js 85 bytes [built] [code generated]
./src/js/name.js 143 bytes [built] [code generated]
webpack 5.22.0 compiled successfully in 87 ms
./src/index.js
을 기준으로 번들링/컴파일 된 ./dist/main.js
파일이 생성된다.
package.json
에서 모드 설정하기
{
"scripts": {
"bundle": "webpack --mode=development",
"production": "webpack --mode=production"
}
}
터미널에 명령어 입력 후 dist/main.js 파일 확인해보기
$ npm run bundle
or
$ npm run production
webpack.confing.js
- 웹팩 설정 파일 생성하기프로젝트 루트에 webpack.confing.js
파일 생성하기
// webpack.confing.js
module.exports = {
entry: "./src/index.js", // 모듈의 의존성 그래프를 만드는 것으로, src/index.js 파일이 기본값으로 설정되며, 지정된 파일에 연관된 모듈과 라이브러리를 포함한 번들을 만든다.
output: {
path: path.resolve(__dirname, "dist"),
filename: "main.js",
}, // 번들 파일 위치와 이름을 지정한다. 번들링이 시작되면 dist 폴더가 생성되고 번들링이 끝나면 dist 폴더 아래에 번들 파일이 생성된다. 기본값은 './dist/main.js'이다. 절대 경로를 사용(path.resolve)하는 것을 권장한다.
module: {
rules: [
{}
],
},
// module.rules는 사용하려는 로더의 규칙을 정의한다. 로더명은 use속성에 추가하고, test는 해당 로더에 적용하려는 파일 확장자를 정규식형태로 지정한다.
};
기본적으로 webpack은 js파일만 인식하기때문에 css 로더를 설치해야한다.
로더없이 번들링을 진행한다면 css 파일을 읽을 수 없기 때문에 loader가 필요하다고 error 메시지가 뜬다.
src/css/style.css
파일을 생성하고 src/index.js
에 import 한다.
/** src/css/style.css **/
body {
background: red;
}
// src/index.js
import sayHello from "./js/sayHello";
import name from "./js/name";
import "./css/style.css";
console.log(sayHello());
console.log(name.isValid("Rich"));
css 파일을 모듈화해주는 로더 설치
$ npm install --save-dev css-loader
다시 돌아와서 webpack.confing.js
에 css-loader
설정하기
module.exports = {
(...)
module: {
rules: [
{
test: /\.css$/,
use: ["css-loader"],
},
],
},
(...)
};
번들링 후 ./dist/main.js
파일에서 style.css
파일이 포함된 것을 볼 수 있다.
/***/ "./src/css/style.css":
/*!***************************!*\
!*** ./src/css/style.css ***!
\***************************/
/***/ ((module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n// extracted by mini-css-extract-plugin\n\n if(true) {\n // 1684140198822\n var cssReload = __webpack_require__(/*! ../../node_modules/mini-css-extract-plugin/dist/hmr/hotModuleReplacement.js */ \"./node_modules/mini-css-extract-plugin/dist/hmr/hotModuleReplacement.js\")(module.id, {\"locals\":false});\n module.hot.dispose(cssReload);\n module.hot.accept(undefined, cssReload);\n }\n \n\n//# sourceURL=webpack://webpack-practice/./src/css/style.css?");
Plugin
플러그인은 모듈 변환 외에 더 다양한 처리를 할 수 있는 도구를 제공한다. 예를 들어 번들 최적화, 에셋 관리 등을 처리할 수 있다. 플러그인 인스턴스를 생성(new 키워드 사용)하여 옵션에 전달하는 방식으로 사용된다.
HtmlWebpackPlugin, CleanWebpackPlugin 플러그인 사용해보기
$ npm install --save-dev html-webpack-plugin clean-webpack-plugin
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
(...)
plugins: [
new HtmlWebpackPlugin(), // HTML 파일을 생성하고, <script> 태그로 번들링된 모든 파일을 HTML에 삽입해준다.
new CleanWebpackPlugin() // CleanWebpackPlugin은 번들이 시작되기 전에 특정 폴더를 지워주는 플러그인으로 주로 빌드 폴더를 정리하는 데 사용된다.
]
};
$ npm run bundle
실행 후 CleanWebpackPlugin
플러그인을 통해 dist 폴더가 삭제되었다가 다시 생성되며, dist/index.html
파일이 추가된 것을 확인할 수 있다. 이때 생성된 index.html
에서는 번들 파일 main.js
를 로드한다.
<!-- dist/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>demo</title>
<script defer src="main.js"></script>
<body>
</body>
</html>
개발 환경 설정하기 - Mode
// webpack.confing.js
module.exports = {
(...)
mode: 'production' // 개발 환경 분리하기
(...)
};
// webpack.dev.confing.js
module.exports = {
(...)
mode: 'development' // 개발 환경 분리하기
(...)
};
package.json
스크립트 수정
npx webpack --mode=development
와 npx webpack --mode=production
과 동일하다.
"scripts": {
"bundle": "webpack --watch --config webpack.dev.config.js",
"production": "webpack" // webpack.config.js 기본 실행
},
References
Webpack docs
번들러 - 웹팩