사용자에게 웹 애플리케이션을 제공하기 위해 모듈화 했던 여러 파일들을 하나로 묶어주는 작업
❗️ 사용자에게 배포하기 위해서는 용량을 줄이고 파일을 통일하는 툴링 작업을 포함한 번들링이 반드시 필요하다.
여러 개의 파일을 하나의 파일로 합쳐주는 모듈 번들러
현재 프론트엔드 애플리케이션 배포를 위해 가장 많이 사용하는 번들러
HTML, CSS, JavaScript 등의 자원을 전부 각각의 모듈로 보고 이를 조합해 하나의 묶음으로 번들링(빌드)하는 도구
모던 웹으로 발전함에 따라
→ 세분화된 모듈 파일이 폭발적으로 증가
모듈 단위의 파일들을 호출 해 브라우저에 띄울 때, 변수의 스코프 문제, 네트워크 쪽의 코스트 문제 같은 복잡성 문제가 발생하기 쉽다.
이러한 복잡성에 대응하기 위해 하나의 시작점(e.g. React App의 index.js)으로부터 의존성을 가지는 모듈을 모두 추적하여 하나의 결과물을 만들어내는 모듈 번들러가 등장하게 되었다.
Webpack에서의 모듈은 JavaScript의 모듈에만 국한되지 않고, HTML, CSS, 이미지 파일들도 전부 포함한 포괄적인 개념
Webpack은 주요 구성 요소인 로더(loader)를 통해 다양한 파일도 번들링이 가능하다.
빌드
개발이 완료된 앱을 배포하기 위해 하나의 폴더(directory)로 구성하여 준비하는 작업
e.g. index.html 파일에 압축시켜 배포에 최적화된 상태를 제공하는 React앱의 npm run build
번들링
모듈 간의 의존성 관계를 파악해 그룹화 하는 작업
의존적 관계에 있는 파일들(import, export) 그 자체 혹은 내부적으로 포함되어 있는 모듈을 묶는 작업
1️⃣ 웹 애플리케이션의 빠른 로딩 속도와 높은 성능을 위해서
웹페이지를 구성하는 코드의 양이 많은 것을 "무겁다"라고 표현하는데, 이것이 무거우면 무거울 수록 웹 페이지의 로딩 속도와 성능을 저하된다.
일반적으로 웹사이트 접근 후 3초 이내에 웹페이지가 뜨지 않으면 상당히 많은 수의 유저가 이탈하게 된다.
로딩 속도가 느리면 느릴 수록 사용자가 폭발적으로 이탈하기 때문에, 로딩 속도를 개선하기 위해 브라우저에서 서버로 요청하는 파일 숫자를 줄이기 시작했다.
2️⃣ Webpack을 통해 같은 타입의 파일들은 묶어서 요청 및 응답을 받을 수 있다.
이를 통해 네트워크 코스트가 획기적으로 줄어든다.
만약 Webpack이 없다면 각 자원들을 일일히 서버에 요청해 얻어와야 한다.
3️⃣ Webpack loader를 통해 JavaScript ES6의 문법들을 ES5로 변환시켜주는 babel-loader를 사용할 수 있게 된다.
Vue의 경우 vue loader, scss 파일의 경우 css 파일로 변환해주는 scss-loader 등의 loader를 사용할 수 있어, 개발자가 원하는 최선의 개발 방식을 선택해 개발할 수 있도록 지원한다.
4️⃣ 상용화 된 프로그램을 사용자가 느끼기에 더욱 쾌적한 환경 및 보안까지 신경쓰면서 노출시킬 수 있다.
Webpack4 버전 이상부터 Develoment, Production 두 가지의 모드를 지원하기 때문에, 여기서 Production 모드로 번들링을 진행할 경우, 코드 난독화, 압축화, 최적화(Tree Shaking) 작업을 지원하기도 한다.
특정 환경을 대상으로 하도록 webpack에 지정하는 속성
Browser Compatibility 와 연관된 속성
Browser Compatibility 브라우저 호환성
: 특정 브라우저나 운영 체제를 통해 웹사이트를 효과적으로 '번역'하여 사용자가 액세스할 수 있고 완전한 기능을 발휘할 수 있음을 의미
target
의 기본값은 web으로, web 외에도 다양한 환경을 컴파일할 수 있다.
module.exports = {
target: ["web", "es5"],
};
해당 config 파일은 브라우저와 동일한 환경에서 사용하기 위해 컴파일할 것이며, 작성된 코드를 es5 버전으로 컴파일하겠다고 지정한 것
webpack에서의 entry는 프론트엔드 개발자가 작성한 코드의 "시작점"
entry 속성은 Entry point라고도 하며, webpack이 내부의 디펜던시 그래프를 생성하기 위해 사용해야 하는 모듈
Webpack은 이 Entry point를 기반으로 직간접적으로 의존하는 다른 모듈과 라이브러리를 찾아낼 수 있다.
module.exports = {
...
entry: "./src/script.js",
};
기본값은 ./src/index.js이지만 entry 속성을 설정하여 다른/여러 entry point를 지정할 수 있다.
생성된 번들을 내보낼 위치와 이 파일의 이름을 지정하는 방법을 webpack에 알려주는 역할
기본 출력 파일의 경우 ./dist/main.js로, 생성된 기타 파일의 경우 ./dist 폴더로 설정된다.
const path = require('path');
module.exports = {
...
output: {
path: path.resolve(__dirname, "docs"), // 절대 경로로 설정을 해야 합니다.
filename: "app.bundle.js",
clean: true
},
};
위의 예제에서는 output.filename
과 output.path
속성을 사용하여 webpack에 번들의 이름과 내보낼 위치를 설정하고 있다.
이때, path
속성을 사용할 때는 path 모듈을 사용해야 한다.
JavaScript와 JSON 파일만을 이해하는 Webpack에 loader를 사용하면
1. 다른 유형의 파일 처리 가능
2. 파일을 유효한 모듈로 변환해 애플리케이션에 사용 가능
3. 디펜던시 그래프에 추가 가능
module.exports = {
...
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
exclude: /node_modules/,
},
],
},
};
test
: 변환이 필요한 파일들을 식별하기 위한 속성 (필수)use
: 변환을 수행하는데 사용되는 로더를 가리키는 속성 (필수)exclude
: 바벨로 컴파일하지 않을 파일이나 폴더를 지정include
속성을 이용해 반드시 컴파일해야 할 파일이나 폴더 지정 가능)위 속성을 넣어 규칙을 정하기 위해서는 module.rules
아래에 정의해야 한다.
번들을 최적화하거나 에셋을 관리하고 환경변수 주입 등의 광범위한 작업을 수행할 수 있다.
const webpack = require('webpack');
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
...
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "src", "index.html"),
}),
new MiniCssExtractPlugin(),
],
};
플러그인을 사용하기 위해서는 require()
를 통해 플러그인을 먼저 요청하고 plugins
배열에 사용하고자 하는 플러그인을 추가해야 한다.
다른 목적으로 플러그인을 여러 번 사용하도록 설정할 수 있기 때문에 new
연산자를 사용해 호출하여 플러그인의 인스턴스를 만들어줘야 한다.
Webpack의 버전 4부터는 선택된 모드에 따라 최적화를 실행한다.
mode
옵션: webpack에 내장된 최적화 기능 사용 가능
module.exports = {
...
optimization: {
minimizer: [
new CssMinimizerPlugin(),
]
}
};
minimize
: TerserPlugin
또는 optimization.minimize
에 명시된 plugins로, bundle 파일을 최소화(압축)시키는 작업 여부를 결정minimizer
: 커스텀된 TerserPlugin
인스턴스를 제공하여 default minimizer
를 재정의할 수 있음위 예제는 mini-css-extract-plugin
에 관련된 번들을 최소화하도록 지시하고 있다.
react
: 리액트 컴포넌트와 Hooks, 라이프 사이클에 대한 정보가 모두 들어있다.
react-dom
: 리액트 코드를 브라우저에 보여준다.
브라우저에서는 JavaScript는 읽을 수 있지만, JSX는 읽을 수 없다.
babel은 JSX를 JavaScript로 변경하여 entry에서 불러올 수 있게 만들어주는 로더의 일종
import 'xxx.css'
처럼 css를 불러오고 적용시키기 위해서는 css-loader가 필요하다.
webpack-dev-server처럼 저장할 때 마다 변경사항을 개발 환경에 적용해주는 라이브러리
react-hot-reloader는 리액트 상태를 유지시켜준다는 추가적인 특징이 있다.
JavaScript로 개발 시 자주 접하는 에러를 방지하기 위한 린터
eslint 역시 많은 config와 plugin이 있는데, 이를 잘 조합한다면 리액트에서 자주 접하는 에러를 미리 발견하는 데 도움이 된다.
JavaScript로 개발 시 통일성있게 코드 형식을 맞출 수 있도록 도와주는 툴
eslint와 조합해서 통일된 코드 형식을 강요할 수도 있다.