https://www.youtube.com/watch?v=TTLHd3IyErM - 드림코딩 Front-end 로드맵 영상
Tools
2. Module Bundler
🔎 Module
애플리케이션의 크기가 커지면 개발하는 과정에서 파일을 여러개로 분리하게 되는데 여기서 분리된 각각의 파일을 모듈(module) 이라 한다.
모듈화의 필요성
- 기능의 분리가 가능하고 인터페이스가 단순해진다.
하나의 파일에 많은 기능들을 작성하면 코드 파악이 힘들고 관리가 어려워진다. 따라서 기능별로 파일을 분리하여 관리할 필요성이 있다. - 각 모듈은 자신만의 스코프를 보장해준다.
하나의 파일에서 모든 코드를 관리하면 변수나 함수명이 중복되거나 다른 기능의 코드끼리 서로 영향을 끼칠 수 있다. 이러한 문제를 해결하기 위해 기능별로 여러 파일로 나누는 것이 필요하다. - 모듈 재사용으로 개발과 유지보수가 용이하다.
공통된 기능이나 UI의 경우 공통 컴포넌트로 분리하여 어디서든 재사용이 가능하다. - 디버깅, 테스트 시 용이성을 제공한다.
각 모듈별로 독립적으로 단위 테스트가 가능하기 때문에 어떤 코드를 리팩토링 하더라도 빠르게 문제 여부를 파악할 수 있다.
.
🔎 Bundler
의존성이 있는 모듈을 하나 혹은 여러개의 파일로 묶어주는 도구로 각 모듈의 의존 관계를 분석하여 브라우저가 인식할 수 있는 자바스크립트 코드로 변환한다.
효과
- 모듈 단위로 개발하여 유지 보수성을 높일 수 있다.
번들러가 없을 경우 각각의 JS 파일을 사용하기 위해 종속성을 고려하여 여러 스크립트 태그를 추가해야하지만, 번들러는 알아서 종속성을 확인하여 묶어주기 때문에 모듈 단위 개발에 용이하다. - 한 번에 많은 요청을 하지 않아도 된다.
모듈 번드러는 JS 모듈을 브라우저에서 실행할 수 있는 단일 JS 파일로 번들링 하주기 때문에 한 번의 네트워크 요청으로 웹 페이지를 로드할 수 있다.
최적화
- Tree Shaking
필요 없는 코드를 제거하고 번들 파일의 크기, 번들링 시간을 줄여준다. - HMR (Hot Module Replacement)
코드가 변경되면 감지하고 브라우저에 최신 코드를 반영하여 자동으로 모듈을 교체한다. 개발자는 따로 새로고침을 하지 않고 변경 사항만 빠르게 확인할 수 있어 개발 속도가 빨라진다. - Code Splitting
번들링한 JS 파일을 청크로 분할하고, 청크가 필요한 경로에만 제공하여 성능을 향상시킨다. - Transformations
트랜스파일러(Babel)를 사용하여 ES6 버전 이상의 스크립트를 사용 가능하게 해준다.
.
🔎 Webpack
특징
- 오랫동안 사용되어 레퍼런스가 다양해 가장 안정적인 번들러
서드파티 라이브러리 관리나 css 전처리, 이미지 에셋관리 등에 있어 우수하고 생태계가 가장 풍부하여 다른 번들러들 보다 안정적이다. - 모든 모듈을 함수로 래핑한다.
각 모듈을 함수로 감싸고 로더와 모듈 캐시를 구현하는 번들을 생성. 런타임 시 각 모듈 함수들이 평가되어 모듈 캐시를 채운다. - JS로 변환하기 위한 로더와 플러그인 설치가 필요하다.
로더 : 번들 되기 전 파일 단위를 처리
플러그인 : 번들된 결과물을 추가로 처리. JS를 난독화 하는 등의 후 처리에 사용 - 하나의 시작점(entry point)으로부터 의존적인 모듈을 모두 찾아내서 하나의 결과물을 만든다.
핵심 개념
Entry
엔트리 포인트는 웹팩이 내부 디펜던시 그래프를 생성하기 위해 사용해야하는 모듈로 의존성 그래프의 시작점을 말한다. 웹팩은 엔트리를 통해서 필요한 모듈을 로딩하고 종속성 그래프를 재귀적으로 빌드한 다음 모든 모듈을 브라우저에 의해 로드되는 작은 수의 번들로 묶는다.
// 단일 엔트리
module.exports = {
entry: './src/index.js'
}
// 항목을 구분하여 사용
module.exports = {
entry: {
login: './src/Login.js',
main: './src/Main.js',
},
...,
}
// 배열로 사용
module.exports = {
entry: ['./src/file_1.js', './src/file_2.js']
...,
}
Output
웹팩으로 번들링을 한 후의 결과물의 파일 경로. out의 [name]은 번들의 파일명이 entry의 이름으로 동적 생성할 수 있도록 해준다.
module.exports = {
entry: {
main: './src/index.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist'),
},
}
// build 시 main.bundle.js 파일이 생성
Loaders
로더는 웹팩이 번들링을 할 때 자바스크립트 파일이 아닌 웹 자원을 변환할 수 있도록 도와준다. TS 같은 다른 언어를 JS 문법으로 변환해주거나 이미지를 data url 형식의 문자열로 변환, css 파일을 JS에서 직접 로딩할 수 있도록 한다.
module.exports = {
entry: './src/index.js',
modules: {
rules: [
{
test: /\.(ts|tsx|js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/,
},
...
]
}
}
Plugins
플러그인은 웹팩의 기본적인 동작에 추가적인 기능을 제공하는 것으로 번들된 결과물을 추가로 처리, 즉 해당 결과물의 형태를 바꾸는 역할을 한다.
module.exports = {
entry: './src/index.js',
modules: {
rules: [
{
test: /\.(ts|tsx|js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/,
},
...
]
},
plugins: [
new HtmlWebpackPlugin({
template: 'public/index.html',
meta: {
'theme-color': '#4285f4',
'description': 'webpack'
},
}),
...
]
}
Mode
웹팩 버전 4 부터 추가된 내용으로 development, production, none 설정이 가능하다. 각 모드의에 따라 웹팩의 결과물이 달라진다.
Code Splitting
웹팩에서는 자동으로 중복되는 코드를 판단하여 별도의 청크로 분할하도록 설정할 수 있다.
장단점
장점
- 다중 리소스를 지원한다.
- on-demand loading을 지원한다.
- 각 모듈을 함수로 감싸기 때문에 안정적이다.
- 최적화가 가능하다. - 코드 스플리팅을 통한 최적화 + mode production을 통한 최적화
- HMR 기능을 통해 일부 모듈의 변경만 감지하여 페이지 갱신 없이 변경사항만 렌더링이 가능하다.
단점
- 설정할 것이 많기 때문에 러닝커브가 있다.
- ES6 모듈 형태로 빌드 결과물을 출력할 수 없다.
- 플러그인에 지나치게 의존하면 번들러가 느려질 수 있다.
.
🔎 rollup
특징
- ES6 모듈 형식으로 빌드 결과물을 생성할 수 있는 번들러.
- 코드를 동일한 수준으로 올리고(Scope Hoisting) 한 번에 번들링한다.
한 번에 하기 때문에 속도는 웹팩보다 빠르고 번들링 결과물도 가볍다. 그러나 변수 충돌에 있어서는 웹팩보다 덜 안정적이다. - 진입점을 다르게 설정하여 번들링이 가능하다.
진입점이 다르기 때문에 중복해서 번들링될 수 있는 부분을 알아내고, 독립된 모듈로 분리가 가능하다. 따라서 코드 스플리팅 측면에서 다른 번들러보다 강점이 있다.
장단점
장점
- 트리쉐이킹이 가능하다.
- 번들링한 결과물의 크기가 비교적 작다.
- 기본 설정이 비교적 간단하다.
- 코드 스플리팅 측면에서 다른 번들러와 비교해 강점을 보인다.
단점
- input, output 이 많아질수록 복잡해질 수 있다.
- 트랜스파일을 하기 위해 플러그인을 사용해야 한다.
.
🔎 parcel
특징
- 설정이 필요 없는(zero-configuration) 웹 애플리케이션 번들러이다.
다른 빌더와 다르게 엔트리 포인트를 지정해 주는 것이 아니라 애플리케이션 진입을 위한 HTML 파일 자체를 읽기 때문에 별도의 설정 없이도 빌드가 가능. 동적 import를 사용해서 출력 번들을 분할할 수 있기 때문에 초기 로드 시 필요한 것들만 로드할 수 있다(더 빠른 페이지 로딩) - Assets 기반으로 번들링 한다.
엔트리 포인트가 없고 HTML 파일을 읽으면서 JS, CSS, 이미지 에셋등을 직접 참조한다. 비슷한 유형의 에셋은 같은 번들로 출력하고 다른 유형은 자식 번들로 만들어 부모 번들에 참조한다. - 속도가 빠르다.
캐싱을 하므로 최고 빌드보다는 두번째 빌드부터 속도가 빠르다. 전체 캐싱을 지원하고 병렬 처리를 지원하여 웹팩보다 빠르게 동작한다. - 자동 변환
Bable, PostCss, PostHTML을 사용하는 코드는 자동으로 변환된다.
장단점
장점
- 애플리케이션의 크기가 커질수록 속도면에서 유의미한 차이를 보인다.
- 별도의 설정파일 없이 다양한 변환을 지원한다.
단점
- Assets 유형으로 번들을 생성하기 때문에 JS 안에 CSS를 포함하도록 하려면 별도의 컴포넌트를 사용해야 한다.
- 웹팩이나 롤업에 비해 좁은 생태계를 가지고 있고 안정성이 떨어진다.
.
참조
https://velog.io/@wynter_j/Bundler-JavaScript-번들러-그리고-Webpack-Parcel-Rollup-Vite...-2