리액트 프로젝트를 진행할 때, 기본적으로 cra를 썼다 최근에는 vite가 떠오르고 있다고 한다.
근데 이게 도대체 뭘까라는 생각에 알아보았다.
webpack은 모듈 번들러로, 의존성을 가진 모듈들을 다루고, 그 모듈로부터 정적인 asset을 생성한다.
사용하고 있는 의존성 모듈들을 빌드 과정을 통해 하나의 스크립트에 포함시키게 된다. 이렇게 의존성 모듈이 포함된 스크립트를 번들이라고 부른다.
참고 : webpack 실전가이드
mkdir webpack-playground && cd webpack-playground
npm install -g webpack webpack-cli
npm install --save-dev webpack webpack-cli
테스트 용 파일을 생성
<!-- index.html -->
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type="text/javascript" src="./bundle.js/main.js"></script>
</body>
</html>
// hello.js
module.exports = "Hello";
// world.js
module.exports = "world";
var Hello = require("./hello");
var world = require("./world");
document.write(Hello + " " + world + "!");
위 파일을 만들고 webpack을 이용해 빌드를 할 수 있다.
npx webpack ./entry.js -o bundle.js
npx는 프로젝트에 로컬로 설치된 npm 패키지를 실행할 때 사용됩니다. Webpack을 로컬로 설치한 경우, npx를 사용하면 전역으로 설치된 Webpack이 아니라 프로젝트 내에서 설치된 Webpack을 실행할 수 있습니다.
그리고 프로젝트 폴더내에 파일이 생긴다
// bundle.js/main.js
(() => {
var r,
e,
o = {
353: (r) => {
r.exports = "Hello";
},
93: (r) => {
r.exports = "world";
},
},
t = {};
function p(r) {
var e = t[r];
if (void 0 !== e) return e.exports;
var s = (t[r] = { exports: {} });
return o[r](s, s.exports, p), s.exports;
}
(r = p(353)), (e = p(93)), document.write(r + " " + e + "!");
})();
만약 여러개의 모듈들이 있다면, 하나의 번들 파일로 브라우저에서 사용할 수 있게 된다.
글에서 생략했지만, css도 추가 할 경우 번들러에도 포함되어 만들어진다.
여러개의 JS파일을 로드하는 것 보다. 하나의 번들 파일로 묶어 사용할 수 있어서 네트워크 성능이 향상되고 페이지 로딩속도가 빨라진다고 한다.
config 파일을 통해 모듈의 의존성 관리와, 웹팩의 시작점, output의 위치 등을 설정 할 수있다.
const path = require("path"); // 경로 모듈 불러오기
const HtmlWebpackPlugin = require("html-webpack-plugin"); // HTMLWebpackPlugin 불러오기
module.exports = {
mode: "development", // 'production' 또는 'none'으로 설정 가능
entry: "./entry.js", // 애플리케이션의 진입점 파일
output: {
filename: "bundle.js", // 출력 번들 파일 이름
path: path.resolve(__dirname, "dist"), // 출력 디렉토리 경로
},
module: {
rules: [
// test: 로더를 적용할 “파일 유형” (CSS, JS..등등)
// use: 로더 이름
{
test: /\.css$/i, // .css 파일에 대한 정규 표현식
// 참고로 우선순위는 오른쪽에서부터 왼쪽으로 정해진다.
use: ["style-loader", "css-loader"], // CSS 파일을 처리할 로더
},
{
test: /\.(png|svg|jpg|jpeg|gif)$/i, // 이미지 파일에 대한 정규 표현식
type: "asset/resource", // 이미지를 처리하기 위한 asset/resource 유형
},
{
test: /\.js$/, // .js 파일에 대한 정규 표현식
exclude: /node_modules/, // node_modules 디렉토리를 제외
use: {
loader: "babel-loader", // 자바스크립트 파일을 트랜스파일링할 Babel 로더
options: {
presets: ["@babel/preset-env"], // Babel 프리셋
},
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./src/index.html", // 사용할 HTML 템플릿 파일
}),
],
devServer: {
contentBase: path.join(__dirname, "dist"), // 개발 서버가 제공할 파일의 루트 디렉토리
compress: true, // gzip 압축 활성화
port: 9000, // 개발 서버가 실행될 포트 번호
},
optimization: {
splitChunks: {
chunks: "all", // 코드 스플리팅 활성화
},
},
};
지금 와서 알았지만 webpack의 역할을 확실히 알게되었다.
그렇다면 cra는 개발환경도 맞춰주고 개발 서버, 빌드를 통한 번들링의 역할도 내부적으로 webpack을 통해 시켜준다