웹팩(Webpack)은 여러 개의 JavaScript
와 JSON
파일들을 하나의 파일로 만들어주는 모듈 번들러이다.
웹팩을 사용하면 의존 관계에 있는 여러 JavaScript
모듈을 묶어서 하나의 파일로 만들어 주기 때문에, ES6
의 import/export
를 지원하지 않는 구형 브라우저에서도 모듈 기능의 사용을 가능하게 만들어주기도 한다.
그리고 loader를 통해 JavaScript
와 JSON
이 아닌 파일들도 모듈로 번들링이 가능하며, 단지 모듈들을 하나로 합치는 것 외에도 이미지를 data URL로 바꾸는 등 각종 자동화 및 최적화 기능도 지원해준다.
웹팩을 사용하기 위한 기본 개념은 크게 아래와 같다.
- Entry(엔트리)
- Output(아웃풋)
- Loaders(로더)
- Plugins(플러그인)
각 항목이 어떤 기능을 하는지 한 번 알아보자!
웹팩은 모듈을 번들링 할 때, Entry Point
가 의존하고 있는 여러 모듈들을 하나로 번들링 한다.
기본값으로 ./src/index.js
를 Entry Point
로 하며, 설정파일에서 아래와 같이 entry
속성을 통해 Entry Point
를 변경할 수 있다.
module.exports = {
entry : './[directory]/[entrySource]'
}
예를 들어 아래와 같은 구조에서 main.js
가 sum.js
를 의존하고 있다고 해보자.
js
|- main.js
|- sum.js
webpack.config.js
이 때 Entry Point
는 main.js
가 되고, 설정은 다음과 같다.
webpack.config.js
module.exports = {
entry : './js/main.js'
}
이 외에도 여러개의 Entry Point
를 지정할 수 있다. 보다 자세한 내용은 Entry Points | 웹팩을 참고하자!
Output(아웃풋)은 단어 그대로 모듈이 번들링한 결과물을 어느곳에 출력할건지 웹팩에게 알려주는 역할을 한다.
const path = require('path');
module.exports = {
output : {
filename : 'bundle.js',
path : path.resolve(__dirname, 'dist', 'js')
}
}
filename
속성은 번들링된 파일의 이름을 정하는 속성이고, path
는 해당 파일이 저장될 디렉터리를 명시해준다.
또한, path
속성은 반드시 절대 경로로 설정해야 하니 이 점에 주의하도록 하자!
위에도 적어놓았지만, 웹팩은 기본적으로 Javascript
와 JSON
파일만을 모듈로 인식한다.
하지만 웹팩은 번들링을 진행하는 과정에서 모듈을 불러올때 Loader(로더)를 이용해서 전처리가 가능한데, 이것 덕분에 .css
와 .ts
등의 파일들도 모듈로 이용이 가능하며 파일을 로드할때 로더에 babel
을 등록해서 트랜스파일링을 진행하는등 다양한 작업이 가능하다.
예를 들어 .css
확장자를 가진 파일을 번들링 하기 위해 css-loader
를 적용한다고 해보자. css-loader
는 css
파일도 모듈에 포함시키기 위해 사용하는 로더이다.
module.exports = {
module : {
rules : [{ test : /\.css$/, use : 'css-loader' }]
}
}
위처럼 module.rules
속성 안에 어떻게 로더를 적용할지 작성한다. test
속성에는 정규표현식을 이용해 어떤 파일에 적용할지 규칙을 명시해주고, use
속성에는 적용할 로더를 지정해주게 된다.
또한, Loader는 체이닝 기능을 지원해서 하나의 test
속성에 여러 개의 loader
를 지정할 수 있다. 예제로 css-loader
를 통해 번들링 된 css
를 실제로 적용하기 위해 style-loader
를 체이닝 시킨다고 해보자.
module.exports = {
module : {
rules : [{ test : /\.css$/, use : ['style-loader', 'css-loader'] }]
}
}
use
속성을 배열 리터럴로 변경하고 적용할 Loader를 지정해주면 된다. 다만 오른쪽에서부터 왼쪽으로 순서대로 적용된다는 점에 주의하도록 하자!
Loader가 모듈을 로드할 때 전처리를 담당했다면, Plugin은 번들링 된 결과물을 최적화 하거나 가공하는 역할을 한다.
예제로 번들링된 결과물을 포함하는 html
파일을 생성해주는 html-webpack-plugin
을 적용해보도록 하자.
const htmlWebpackPlugin = require('html-webpack-plugin');
const htmlWebpackPluginOption = { template : './html/main.html' };
module.exports = {
plugins : [ new htmlWebpackPlugin(htmlWebpackPluginOption) ]
}
보다시피 plugin
은 plugins
속성 안에 배열 형태로 추가하게 되며, 반드시 new
연산자를 이용해 생성자 함수로 생성한 인스턴스를 추가해야 한다.
위에서 익힌 내용을 토대로 간단한 실습을 통해 babel
을 포함한 각종 Loader
및 Plugin
을 적용해서 실제로 파일을 번들링 해보자!😆
먼저, npm
을 사용하기 위해 초기화부터 진행하도록 하자.
npm init -y
그리고 번들링에 사용할 파일들을 적절하게 만들어주자. 실습에서 사용할 파일의 구조 및 내용은 아래와 같다.
main.js
module.js
main.css
main.html
그럼 이제 실습에 필요한 각종 패키지들을 설치해보자!
- webpack :
npm i -D webpack webpack-cli babel-loader css-loader style-loader html-webpack-plugin- babel :
npm i -D @babel/core @babel/cli @babel/preset-env
이번 실습에서는 babel-loader
를 사용하기 때문에 babel.config.json
파일을 생성하고 babel
설정을 해주자.
babel.config.json
babel
설정이 끝났다면, webpack
에 대한 설정도 해주도록 하자!
webpack.config.js
output
directory는 /dist/js다.
제일 하단의 target
옵션을 지정해준 이유는 Webpack v5
부터 ES6
를 기준으로 트랜스파일링 하기 때문에 babel
을 적용해도 es5
문법으로 제대로 변환되지 않는 문제가 생기기 때문이다.
설정이 모두 끝났다면 npx webpack
명령을 통해 번들링을 진행해보자!
정상적으로 실행이 됐다면 위와 같은 로그를 남기게 된다. 번들링된 파일들을 확인해보자!
/dist/js/bundle.js
webpack
이 자동으로 압축을 진행해서 가독성은 떨어지지만 번들링 된 결과물이다.
/dist/html/index.html
번들링된 파일을 자동으로 html
에 삽입해주는 html-webpack-plugin
에 의해 생성된 새로운 html
파일이다.
그럼 이제 index.html
파일을 실행해서 정상적으로 동작하는지 확인해보도록 하자!
크롬 브라우저에서는 정상적으로 실행되고 있는것을 확인할 수 있다. 이제 구형 브라우저에서도 정상적으로 실행되는지 보자.
황천의 브라우저 IE11에서도 정상적으로 동작하는 것을 확인할 수 있다. 휴~
이로써 기본적인 웹팩 설정 및 사용이 가능해졌다. 더욱 자세한 내용은 웹팩 공식 문서 webpack 을 참고하도록 하자!
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.0",
"@babel/preset-env": "^7.16.4",
"babel-loader": "^8.2.3",
"css-loader": "^6.5.1",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.64.2",
"webpack-cli": "^4.9.1"
참고자료
완전 깔끔해요! 배워갑니당👍🏻