react 앱을 개발하면 수많은 .js
파일들이 나오는데, 이를 웹페이지 상에서 그대로 모두 다운받으려면 많은 파일을 다운받아야한다.
그래서 하나의 파일로 묶어 제공하는데, 이를 번들링이라고 한다.
브라우저가 여러 개의 파일을 요청하는 대신, 하나의 큰 파일을 요청하는 것이 더 효율적이다.
HTTP/1.1에서는 병렬 요청에 제한이 있기 때문에, 파일 요청 수가 많을수록 성능 저하가 발생할 수 있다.
모듈화된 코드(예: ES6 모듈, CommonJS 등)는 서로 의존성이 있는데, 번들링 도구는 이러한 의존성을 분석하고, 최적의 순서로 코드를 결합한다.
번들링 도구는 코드를 결합하면서 불필요한 코드를 제거하거나, 압축하여 파일 크기를 줄이는 등의 최적화를 수행한다.
웹팩(Webpack) 은 자바스크립트 애플리케이션을 위한 모듈 번들러이다.
vite, webpack 등 다양한 모듈 번들러가 존재한다.
웹팩은 모든 파일을 모듈로 취급하고, 의존성을 분석하여 하나의 번들 파일 또는 여러 개의 번들 파일로 결합한다.
웹팩은 자바스크립트 파일뿐만 아니라, CSS, 이미지, 폰트 등 다양한 자산 파일도 번들링할 수 있다.
이를 위해 웹팩은 로더를 사용하여 파일을 처리한다.
예를 들어, css-loader와 style-loader를 사용하여 CSS 파일을 자바스크립트 파일에 포함시킬 수 있다.
웹팩은 플러그인 시스템을 제공하여, 번들링 과정 중 추가적인 기능을 수행할 수 있다.
예를 들어, HtmlWebpackPlugin을 사용하여 번들된 파일을 포함하는 HTML 파일을 자동으로 생성할 수 있다.
웹팩은 코드 스플리팅을 지원하여, 필요한 코드만 로드하고, 초기 로딩 시간을 줄일 수 있다.
이를 통해 더 나은 성능을 제공한다.
웹팩은 config 파일을 통해 맞춤 설정이 가능하다.
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js', // 번들링의 진입점
output: {
filename: 'bundle.js', // 생성될 번들 파일 이름
path: path.resolve(__dirname, 'dist'), // 번들 파일이 저장될 경로
},
module: {
rules: [
{
test: /\.css$/, // .css 파일에 대한 로더 설정
use: ['style-loader', 'css-loader'],
},
{
test: /\.(png|svg|jpg|gif)$/, // 이미지 파일에 대한 로더 설정
use: ['file-loader'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // 템플릿 HTML 파일
}),
],
};
번들링이 되는 진입점으로 프레임워크나 라이브러리 환경에 따라 달라진다.
react는 index.js
를 최초로 실행해 css를 땡겨오거나 js를 땡겨오기 때문에 보통 위처럼 설정한다.
어느 환경에서 사용되는지 정의하는 것으로, node.js
라면 node
, react
같은 환경이라면 web
, next.js
라면 보통 nextjs.config.js
에서도 이를 관리할 수 있게 한다.
최종적으로 번들링한 파일을 어떤 이름으로 설정할지 정하는 것으로, 기본 경로는 dist/main.js
이다.
따로 경로를 지정해줄 수 있다.
css
나 이미지
들도 모듈로 취급하여 번들링을 해야하기 때문에, rules
로 추가할 수 있다.
module
로도 커버를 칠 수 없는 역할을 한다.
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
...(process.env.NODE_ENV === 'production'
? [new MiniCssExtractPlugin({ filename: '[name].css' })]
: []),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
patterns: [
{ from: 'assets', to: 'assets' },
],
}),
]
css
, js
를 따로 모듈로 번들하면 html
파일 내부의 <script/>
태그로 포함시켜야하는데 이를 자동으로 해주는 HtmlWebpackPlugin
이 있다.
CleaWebpackPlugin
은 이전에 빌드한 파일을 현재 빌드해서 나올 파일과 겹치지 않도록, 미리 지우고 빌드시키도록 도와준다.
MiniCssExtractPlugin
은 .js
파일 마다 .css
를 작게 나누어 추출해주는 번들러로, 실제 배포중인 파일에서 여러개의 .css
로 나눠받는 것이 좋기에 개발 환경에 따라 될지 말지 설정할 수 있다.
모듈을 해석하는 방법을 정의해놓은 것으로, 파일 확장자 명이나 경로를 별칭으로 달아줄 수도 있다.
resolve: {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
alias: {
'@components': path.resolve(__dirname, 'src/components/'),
},
}
따로 개발서버를 설정하여 핫 리로드를 설정할 수 있다.
devServer: {
contentBase: './dist',
hot: true,
}
바벨(Babel)은 .js
코드를 .js
코드로 변환해주는 도구이다.
왜 굳이 변환하냐? 하면 웹브라우저는 다양하고, 각 브라우저마다 다양한 버전이 있을 수 있다.
또한, 웹브라우저에 해당되는 것이 아니라, node.js
일 수도 있기 때문이다.
다양한 환경에서 .js
가 해석되도록 바꿔주는 역할을 하는 것이 babel
이다.
최신 ECMAScript 표준에 추가된 문법(예: 화살표 함수, 클래스, 템플릿 리터럴 등)을 구 형태의 자바스크립트로 변환한다. (ES6+을 ES5로 고정하거나, next.js가 사용하는 esnext를 es5로 하는 등)
바벨은 다양한 변환 규칙을 플러그인으로 제공하며, 개발자는 필요에 따라 이 플러그인들을 추가하거나 커스터마이즈할 수 있다.
예를 들어, @babel/preset-env
플러그인은 목표 환경에 맞게 최소한의 변환만 수행할 수 있도록 설정할 수 있다.
바벨을 사용하여 작성된 최신 자바스크립트 코드는 구형 브라우저나 다양한 환경에서도 동작할 수 있도록 변환됩니다.
이는 특히 웹 개발에서 크로스 브라우징 문제를 해결하는 데 유용하다.
바벨은 일반적인 변환 설정을 미리 정의해 놓은 프리셋을 제공한다.
예를 들어, @babel/preset-env
는 목표 환경에 따라 필요한 변환 규칙을 자동으로 적용하는 프리셋이다.
Typescript는 브라우저가 이해하지 못하므로 이를 Javascript로 변환해주는 역할도 한다.
// webpack.config.js
module.exports = {
// ... 기본 설정
module: {
rules: [
{
test: /\\.ts?$/,
exclude : /node_modules/,
loader:'ts-loader',
},
{
test: /\\.css$/,
use: ['style-loader','css-loader']
},
{
test: /\\.jsx?$/,
loader: 'babel-loader', //js나jsx파일에 바벨로더를 적용해 최신문법이 옛날 브라우저에서도 돌아갈 수 있도록 해준다.
options: {
presets: [
[
'@babel/preset-env', {
targets: { node: 'current' }, // 노드일 경우만
modules: 'false',
useBuiltIns: 'usage'
}
],
'@babel/preset-react', // 리액트를 쓴다면
'@babel/preset-typescript' // 타입스크립트를 쓴다면
],
]
},
};
@babel/preset-###
같은 친구들을 사용해서 .tsx
, .jsx
같은 react 환경의 코드도 브라우저에 돌아가도록 할 수 있다.