webpack.config.js 파헤치기

Goody·2021년 7월 1일
13

삽질기록⛏

목록 보기
2/6

왜 하게 되었나?

CRA 없이 리액트 개발환경을 구성해보려고 하는데,

대부분의 블로그들이

" 웹팩 환경설정은 webpack.config.js 파일에서 하는거고, 제 코드를 복붙하시면 됩니다 " 라는 식이었습니다.

나중에 언젠가 웹팩 설정때문에 발목이 잡힐 것 같아서, webpack.config.js 의 설정들을 파헤쳐보기로 했습니다.

💡 이 포스팅에서는 React + TypeScript 설정을 기반으로 합니다.

학습중인 주제이므로, 틀린 내용이 있을 수 있습니다.
댓글로 피드백 주시면 감사하겠습니다.


웹팩(webpack)이란?

자바스크립트 코드가 많아지면 자연스럽게 파일을 나누게 되는데, 이 때 파일 하나 하나 불러오는 게 네트워크 속도를 느리게 할 수 있겠죠.

이 때 웹팩이 수많은 자바스크립트 파일을 하나의 파일로 묶어(bundle) 네트워크 비용을 최소화해줍니다.

흩어진 파일들을 확장자별로 번들링해주는 웹팩.

https://webpack.js.org/


필요한 모듈 블러오기

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const mode = process.env.NODE_ENV || "development";
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

우선 path 는 번들의 엔트리와 아웃풋의 경로 설정에 쓰이게 되는데, 자세한 것은 밑에서 설명하겠습니다.

mode 는 프로젝트가 프로덕트 모드 혹은 개발모드냐를 저장하고 있는 변수입니다.

HtmlWebpackPluginCleanwebpackPlugin 은 npm에서 다운받은 모듈로, 각각 html 파일의 번들링과 아웃풋 폴더의 클린업을 할 때 사용합니다.


export 설정

module.exports = {}

webpack.config.js 파일을 어디에선가 require() 메소드로 끌어다 쓰기 때문에, module.exports 로 설정들을 내보내줍니다.


엔트리

entry: {
    app: path.join(__dirname, "src", "index.tsx"),
},
    
// 최종 html에서 사용할 js 파일은 app.js 파일인데, 이 파일은 엔트리 포인트인 src/index.tsx로부터 빌드됩니다.    

웹팩으로 여러 코드들을 번들링 하려면 복잡하게 얽힌 코드들의 맨 처음 시작점이 되는 파일이 필요한데, 이를 엔트리 파일 이라고 부릅니다.

엔트리파일을 명시해줘야 웹팩이 번들링 시작점을 찾을 수 있습니다.


아웃풋

output: {
	filename: "[name].js", // [app].js (엔트리의 키가 app이므로)
	path: path.resolve(__dirname, "dist"), 
 // 웹팩 설정 완료 후 빌드하면 프로젝트 루트 경로에 dist폴더가 생기고 그 안에 번들링 결과물인 [app].js가 들어있게 됩니다.
},

엔트리 파일로부터 복잡하게 얽혀있던 코드들을 하나의 파일로 번들링한 결과물을 설정하는 단계입니다.

filename 은 번들링된 파일의 이름을 설정합니다.

path 는 번들링된 파일을 어느 경로에 저장할지 설정합니다.


💡 path.join() 과 path.resolve 의 차이

path.join() 과 path.resolve() 의 차이는 join()의 경우 인자들을 모두 concat 하지만, resolve는 인자들을 루트로 인식합니다.

예시:

path.join('/a', '/b') // Outputs '/a/b'

path.resolve('/a', '/b') // Outputs '/b'

로더

module: {
	rules: [
		{
			test: /\.(ts|tsx)$/, // tsx나 ts파일을 발견하면
			use: "ts-loader", // 해당 loader를 통해서 ts를 js로 변환합니다.
			exclude: /node_modules/, // 패키지 폴더는 제외합니다.
		},
	],
},

웹팩은 자바스크립트만을 모듈화 대상으로 인식하기 때문에,

타입스크립트나 바벨도 웹팩이 인식하게끔 설정해줘야 합니다.

여기서는 일단 타입스크립트만 로더로 불러왔습니다.


플러그인

plugins: [
	new HtmlWebpackPlugin({
			// 빌드시 html에 값을 전달, html 변경 & html 코드 압축(공백, 주석제거) & webpack으로 빌드한 번들 파일을 자동으로 html에 추가
		template: "./src/index.html", // index.html 파일을 템플릿으로 씁니다.
		templateParameters: {
				// 해당 템플릿에 전달하는 인자들
		env: process.env.NODE_ENV === "production" ? "" : "[DEV]",
		},
		minify:
			process.env.NODE_ENV === "production" // 프로덕션 모드일경우 공백,주석 제거
				? {
						collapseWhitespace: true,
						removeComments: true,
					}
				: false,
		}),
	new CleanWebpackPlugin(), // 빌드때마다 dist 폴더 클린업
],

로더가 파일단위로 처리해주는 반면, 플러그인은 번들된 결과물을 처리합니다.

HtmlWebpackPlugin 의 경우 template 에 지정한 html 파일을 번들링하는데, 이때 공백이나 주석을 제거하는 옵션을 넣어 용량을 줄일 수 있습니다.

CleanWebpackPlugin 의 경우, 번들링 결과물이 담기는 장소인 dist 폴더를 매 빌드 때마다 비워주는 플러그인입니다.


소스코드

// webpack.config.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const mode = process.env.NODE_ENV || "development";
const { CleanWebpackPlugin } = require("clean-webpack-plugin");

module.exports = {
	mode,
	entry: {
		// 최종 index.html에서 사용할 js 시작점은 app.js 파일인데, 이 파일은 src/index.tsx로부터 빌드된다.
		app: path.join(__dirname, "src", "index.tsx"),
	},
	output: {
		filename: "[name].js", // [app].js
		path: path.resolve(__dirname, "dist"), // 빌드하면 dist폴더가 생기고 그 안에 번들링 결과물인 [app].js가 들어있다.
	},
	resolve: {
		extensions: [".jsx", ".js", ".tsx", ".ts"], // 웹팩에서 처리해주는 확장자들
	},
	module: {
		rules: [
			{
				test: /\.(ts|tsx)$/, // tsx나 ts파일을 발견하면
				use: "ts-loader", // 해당 loader를 통해서 ts를 js로 변환한다.
				exclude: /node_modules/,
			},
		],
	},
	plugins: [
		new HtmlWebpackPlugin({
			// 빌드시 html에 값을 전달, html 변경 & html 코드 압축(공백, 주석제거) & webpack으로 빌드한 번들 파일을 자동으로 html에 추가
			template: "./src/index.html", // index.html 파일을 템플릿으로 쓴다.
			templateParameters: {
				// 해당 템플릿에 전달하는 인자들
				env: process.env.NODE_ENV === "production" ? "" : "[DEV]",
			},
			minify:
				process.env.NODE_ENV === "production" // 프로덕션 모드일경우 공백,주석 제거
					? {
							collapseWhitespace: true,
							removeComments: true,
					  }
					: false,
		}),
		new CleanWebpackPlugin(), // 빌드때마다 dist 폴더 클린업
	],
};

REFERENCE

김정환님 블로그 : https://jeonghwan-kim.github.io/js/2017/05/15/webpack.html

kihyeon8949 님 벨로그 : https://velog.io/@kihyeon8949/CRA%EC%97%86%EC%9D%B4-Tool-React-Typescript-%EC%84%B8%ED%8C%85%ED%95%98%EA%B8%B0

웹팩 공식 사이트 : https://webpack.js.org/

path.join() 과 path.resolve() 의 차이 : https://stackoverflow.com/questions/35048686/whats-the-difference-between-path-resolve-and-path-join

0개의 댓글