🔥 목차 🔥
1. 번들
2. Webpack
🧐 그렇다면 꼬! 🧐
💡 번들
- 일반적 번들의 정의는 여러 제품이나, 프로그램을 묶어서 패키지로 제공하는 행위를 함
- 프론트엔드에서의 번들은 사용자에게 웹 애플리케이션을 제공하기 위한 파일 묶음임
번들링의 필요성
- 번들링 작업에서는 필연적으로 용량을 줄이고 파일을 통일하는 툴링 작업이 필요하게 됨 즉 소프트웨어를 잘 만들어도 사용자에게 배포하기 위해서는 번들링이 꼭 필요함
- 번들링이 필수적인 요소는 아니지만 특정한 문제가 생겼을때 해결하기 어려울 수 있음
- 두개의 .js파일에서 같은 변수를 사용하고 있어서 변수간의 충돌이 일어남
- 딱 한번 불러오는 프레임워크 코드가 8MB라서 인터넷 속도가 느린 국가의 모바일 환경에서 사용자가 불편을 호소함
- 번들 파일 사이즈를 줄이기 위해 파일의 공백을 모두 지웠는데 가독성이 너무 떨어져서 코딩하기가 어려움
- 배포 코드가 너무 읽기 쉬워서 개발을 할 줄 아는 사용자가 프론트엔드 애플리케이션을 임의로 조작하여 피해가 발생함
💡 Webpack
- 프론트엔드 애플리케이션 배포를 위해서 가장 많이 사용하는 번들러임
- 실리콘벨리나 국내 IT 대기업을 막론하고 프론트엔드 애플리케이션을 대규모 유저에게 제공하기 위해 가장 많이 사용하는 방법임
- Webpack은 여러개의 파일을 하나의 파일로 합쳐주는 모듈 번들러를 의미함
- 모듈 번들러는 HTML,CSS,JS등의 자원을 전부 각각의 모듈로 보고 그것들을 조합해서 하나로 번들링(빌드) 하는 도구임
모듈번들러
- 모듈 번들러가 등장한 배경에는 이유들이 있다
- 모든웹으로 발전하면서 JS코드양이 절대적으로 증가했다
- 대규모 의존성 트리를 가지고있는 대형 웹앱이 등장해서 세분화된 모듈파일이 증가했다
- 위 모듈단위의 파일들을 호출해서 브라우저에 띄워야 하는데 JS언어의 특성에 따라 발생하기 쉬운 각 변수들의 Scope문제를 해결해야 했고
- 각 자원을 호출할 때 생겨나는 네트워크쪽의 코스트도 신경써야 했다
- 위 이유들에 대응하기 위해서 하나의 시작점으로 의존성을 가지는 모든 모듈을 추적해서 하나의 결과물을 만들어내는 모듈 번들러가 등장함
Webpack에서의 모듈
- 웹팩에서의 모듈은 HTML,CSS,.jpg,.png와 같은 확장자들도 전부 포함한 포괄적 개념임
- Webpack은 주요 구성 요소인 로더(loader)를 통해서 다양한 파일도 번들링이 가능함
빌드와 번들링
- 빌드
- 개발이 완료된 앱을 배포하기 위해서 하나의 폴더로 구성하여 준비하는 작업임
- React App을 기준으로 설명하면, nom run build를 실행하면 React Build에 작업이 진행되고
- index.html 파일에 압축 되어 배포에 최적화된 상태를 제공해줌
Webpack에 필요성
- 위 내용들을 적어놓은 이유이다
- 결국 전체적인 내용들이 가르키고있는건 웹앱의 최적화이다
- 웹페이지를 구성하는 코드의 양이 많은것을 무겁다라고 표현한다
- 이것이 무거우면 무거울수록 웹 로딩속도와 성능이 저하된다
- 여담으로 일반적으로 유저는 하나의 웹사이트에 접근하는 순간부터 3초 이내에 웹페이지가 뜨지않으면 굉장히 많은 수가 더는 기다리지않고 이탈을 선택한다
- 사용자의 이탈을 막기위해선 최적화가 필요했고 그 방법은 브라우저에서 서버로 요청하는 파일의 숫자를 줄이는 것이였다
- Webpack으로 처리된 파일들은 같은 타입의 파일들을 묶어서 요청 및 응답을 받을수 있기 때문에 네트워크 코스트가 획기적으로 줄어듬
- Webpack loader를 사용하면 일부 브라우저에서 지원하지 않는 JS ES6의 문법들을 ES5로 변환해주는 babel-loader를 사용할 수 있게됨
웹팩의 핵심 개념
- Entry
- 엔트리 포인트는 Webpack이 내부의 디펜던시 그래프를 생성하기 위해 사용해야하는 모듈임
- Webpack은 엔트리 포인트가 의존하는 다른 모듈과 라이브러리를 찾아냄
module.exports = {
entry: './path/to/my/entry/file.js',
};
- Output
- 생성된 번들을 내보낼 위치와 이 파일의 이름을 지정하는 방법을 Webpack에 알려주는 역할을 함
- 기본 출력 파일의 경우에는
./dist/main.js로
- 생성된 기타 파일의 경우에는
./dist폴더로 설정됨
const path = require('path');
module.exports = {
entry: './path/to/my/entry/file.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'my-first-webpack.bundle.js',
},
};
- loaders
- Webpack은 기본적으로 JSON,JS파일만 확인 할 수있음
- 하지만 Loaders를 사용하면 다른 유형의 파일을 처리하거나 유효한 모듈로 변환해서 앱에 사용하거나 디펜던시 그래프에 추가함
- 상위 수준에서의 로더는 설정에 두가지 속성을 가짐
- 변환이 필요한 파일들을 식별하는 test속성
- 변환을 수행하는데 사용하는 로더를 가르키는 use속성
- 바벨로 컴파일을 하지 않을 파일이나 폴더를 지정하는 exclude속성
const path = require('path');
module.exports = {
output: {
filename: 'my-first-webpack.bundle.js',
},
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
};
- 위 설정에서 test와 use를 사용하기 위해서 rules 속성을 정의함
- 해당내용은 Webpack컴파일러에게 require()/import문에서 .txt파일로 확인되는 경로를 발견하면 번들추가 전에 raw-loader를 사용해서 변환하라는 내용임
- Webpack의 규칙을 설정할때 rules가 아니라 module.rules로 정의해야함
- 정규식을 사용해서 파일을 매칭할 때 따옴표를 사용하면 안됨
- ex)
/\.txt$/는 ’/\.txt$/’와 같지 않음
- 전자는 .txt로 끝나는 모든파일과 일치하도록 지시하고 후자는 Webpack에 절대경로 ‘.txt’를 가진 단일파일과 일치하도록 지시함
- Plugins
- Plugin을 사용하려면
require()를 통해 플러그인을 요청하고 plugins 배열에 추가해야함
- 대부분의 플러그인은 옵션을 통해 사용자가 지정 할 수 있음
- 다른 목적으로 플러그인을 여러번 사용하도록 설정 할 수 있음으로
new연산자로 호출해서 플러그인의 인스턴스를 만들어야함
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
module.exports = {
module: {
rules: [{ test: /\.txt$/, use: 'raw-loader' }],
},
plugins: [new HtmlWebpackPlugin({ template: './src/index.html' })],
};
- Optimization(최적화)
- 최적화 하기위해 다양한 옵션이 지원되는데 대표적으로
minimize 와 minimizer등을 사용함
module.exports = {
...
optimization: {
minimizer: [
new CssMinimizerPlugin(),
]
}
};
- minimize:
TerserPlugin 또는 optimization.minimize에 명시된 plugins로 bundle 파일을 최소화하는 작업 여부를 결정
- minimizer:
default minimizer을 커스텀된 TerserPlugin 인스턴스를 제공해서 재정의할 수 있음
- Mode
mode파라미터를 development, production, none으로 설정하면 Webpack에 내장된 환경별 최적화를 활성화 할 수 있음
- 기본값은
production임
module.exports = {
mode: 'production',
};
- Browser Compatibility
- ES5가 호환되는 모든 브라우저를 지원함
- Webpack은
import()와 폴리필을 로드해야함