[MFA] webpack.config.js
들어가며
채팅 플랫폼 개발을 진행하면서, 직접 webpack.config.js를 설정해보고, 처음엔 Webpack 설정이 그저 여러 설정들의 모임처럼 보였지만, 실제내 손으로 하나하나 설정해보니 예상외로 여러 시행착오를 겪었다. Webpack의 각 옵션들이 실제로 어떤 역할을 하는지, 왜 필요한지를 명확하게 이해 하기위해 이번 글에서는 Webpack의 주요 설정 옵션들을 하나씩 깊이 있게 살펴보려고 한다.
Entry(엔트리)
엔트리는 Webpack이 프로젝트를 '빌드'하는 시작이다. 이 설정은 Webpack에게 어떤 파일부터 모듈들을 조합하여 번들을 하기위한 진입점 이다.
entry: './src/index.js'
여기서 './src/index.js'라는 경로는 Webpack이 작업을 시작할 첫 파일을 가리키고, 이 파일은 다른 파일들과 연결되어 있다. Webpack은 이 연결들을 따라가면서 필요한 모든 파일을 찾아낸다. 일반적으로 엔트리는 하나지만 만약 여러 개의 시작점이 필요하다면 이를 여러 개 설정할 수도 있다.
Output (출력)
Output 설정은 Webpack이 처리한 파일들을 어디에, 어떤 이름으로 저장할지 결정하는 부분.
output: {
path: __dirname + '/dist',
filename: '[name].bundle.js'
// filename: '[name].[hash].bundle.js'
// filename: '[name].[chunkhash].bundle.js' => [name].asdf3dsff.bunlde.js 와 같이 생김
}
__dirname
Webpack 설정 파일인webpack.config.js에서 '__dirname'을 사용하면, 이 파일이 위치한 디렉토리의 절대 경로를 얻을 수 있다. 이를 통해, 다른 경로를 지정할 때 기준점으로 사용할 수 있다.
path
Webpack이 생성한 번들 파일을 저장할 디렉토리의 절대 경로를 지정.
filename
1. [name]
- 예시: filename: '[name].bundle.js'
- 설명: [name]은 엔트리 포인트의 이름을 파일 이름에 포함. 예를 들어, 엔트리가 { app: './src/app.js', admin: './src/admin.js' }라면, Webpack은 'app.bundle.js'와 'admin.bundle.js'라는 두 개의 번들을 생성.
2. [hash] 또는 [contenthash]
- 예시: filename: '[name].[hash].bundle.js'
- 설명: [hash]는 빌드마다 고유한 해시 값을 파일 이름에 추가. 이는 파일 캐싱을 관리할 때 유용하다. 파일 내용이 변경될 때마다 해시 값도 변경되어, 브라우저가 변경된 파일을 새로운 파일로 인식.
3. [chunkhash]
- 예시: filename: '[name].[chunkhash].bundle.js'
- 설명: [chunkhash]는 각 청크(chunk)의 내용에 따라 생성되는 해시 값을 사용. 이는 특히 여러 엔트리 포인트를 가진 경우 각각의 번들 파일에 대해 고유한 해시 값을 생성할 때 유용하다.
contenthash 파일의 content를 기반으로 hash값 생성
chunkhash entry 기반으로 hash 생성
Module
Webpack은 기본적으로 자바스크립트와 JSON 파일만 해석한다. module 설정은 Webpack에게 다른 유형의 파일들(html, css, image)을 어떻게 처리(예: loader)할지 알려준다. 이 설정은 여러 가지 규칙(rules)을 포함할 수 있으며, 각 규칙은 특정 유형의 파일을 어떻게 처리할지 정의한다.
Loader
Loader는 module 설정 내에서 사용되며, Webpack이 이해하지 못하는 파일 유형을 변환하여 Webpack이 처리할 수 있는 유효한 모듈 형식으로 만든다. 예를 들어, CSS, 이미지, 폰트 파일 등을 JavaScript 파일로 변환하는 역할을 한다.
module: {
rules: [
{ test: /\.css$/, use: ['style-loader', 'css-loader'] },
{ test: /\.js$/, use: 'babel-loader' },
{ test: /\.(png|svg|jpg|gif)$/, use: 'file-loader' }
]
}
각 부분 설명
- rules: 파일 처리 규칙의 배열이다. 여기서 각 규칙을 정의.
- test: 처리할 파일 유형을 정의하는 조건. 주로 정규 표현식을 사용하여 파일 확장자를 지정.
- use: 해당 유형의 파일을 처리할 로더를 지정한다. 예를 들어, .css 파일에는 css-loader를, .js 파일에는 babel-loader를 사용한다. use에 배열 대신 객체를 적용하면 아래와 같이 loader의 옵션을 설정할 수 있다.
style-loader
style-loader는 css-loader가 처리한 CSS를 <style> 태그로 만들어 HTML 문서의 <head> 부분에 추가한다. 이로써, JavaScript로 로드된 CSS 스타일이 실제 웹 페이지에 적용된다.
css-loader
css-loader는 CSS 파일을 JavaScript로 로드하는 역할을 한다. 이 로더는 CSS 파일을 읽어서 JavaScript로 변환하고, 이를 Webpack 번들에 포함시킨다. 즉, CSS 파일을 모듈처럼 import 할 수 있게 해준다.
일반적으로, use 배열 내에서 style-loader 를 css-loader 보다 앞에 위치시켜 사용한다. 이는 Webpack이 로더를 열의 끝에서부터 순차적으로 적용하기 때문이다. 따라서 css-loader가 먼저 CSS 파일을 처리하고, 그 결과를 style-loader 가 받아 스타일 태그로 변환하는 순서로 작업이 진행된다. 만약 순서가 바뀌면 정상작동을 하지 않는다.
use에 옵션 추가
use: [
'style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
}
]
이 설정은 css-loader에게 모든 CSS 파일을 CSS 모듈로 처리하도록 지시한다. 결과적으로, CSS 파일 내의 클래스 이름은 고유한 이름으로 변환되어, 스타일 충돌 없이 안정적으로 사용할 수 있다.
실제 적용 예
- CSS 파일 예시: styles.css 파일 내에 .button { ... }이라는 클래스가 있다고 가정한다.
- JavaScript에서의 사용: CSS 모듈이 활성화되면, 이 클래스는 JavaScript에서 import styles from './styles.css'를 통해 가져온 후, styles.button처럼 접근하여 사용한다. 이렇게 하면 styles.button은 실제로 "button_button__3KmXo"와 같이 변환된 고유한 이름을 가지게 된다.
다음에 이어서..