😮 웹팩 ? 웹팩이 뭐야
프론트엔드 면접 단골 질문에 있는 "웹팩이 무엇인지"에 대해 잘 답변하기 위해 정리해본다.
📃 웹팩 공식 문서에 따르면
webpack은 자바스크립트를 위한 정적 모듈 번들러이다.
모듈은 무엇을 의미하는 걸까?
- 모듈이란 프로그래밍 관점에서 특정 기능을 갖는 작은 코드 단위를 의미한다. 예를 들면 js코드에서 쓰는 함수라고 생각하면 편하다.
그렇다면 모듈 번들링이 뭐지?
- 웹 애플리케이션을 구성하는 몇십, 몇백 개의 자원들을 하나의 파일로 병합 및 압축해주는 동작을 모듈 번들링이라고 한다.
정리하자면 하나의 웹 서비스를 구성하는 자바스크립트 파일, jps 파일 파일들의 연관 관계를 파악해서 하나로 합쳐주겠다! 라는게 웹팩의 역할이다.
😎 웹팩이 왜 필요할까 ?
웹팩의 등장
웹팩이 등장한 이유는 크게 3가지이다.
1. 파일 단위의 자바스크립트 모듈 관리
// app.js
var num = 10;
function getNum() {
console.log(num);
}
// main.js
var num = 20;
function getNum() {
console.log(num);
}
app.js 와 main.js에서 같은 변수 num을 사용하고 있다고 해 보자. 이 두 파일을 하나의 html에서 불러온다고 생각해보자.
<!-- index.html -->
<html>
<head>
<!-- ... -->
</head>
<body>
<!-- ... -->
<script src="./app.js"></script>
<script src="./main.js"></script>
<script>
getNum(); // 20
</script>
</body>
</html>
index.html의 getNum() 함수의 출력 값은 main.js의 값인 20이 나오게 된다.
app.js 에서 선언한 변수를 main.js에서 다시 선언하고 할당했기 때문인데, 이러한 문제점이 복잡한 애플리케이션을 개발할 때 발생한다고 생각하면 정말 끔찍하다..
2. 웹 개발 작업 자동화 도구
웹 서비스를 개발하고 배포할 때 이러한 작업들을 해야 한다.
- HTML, CSS, JS 압축
- 이미지 압축
- CSS 전처리기 변환
이러한 귀찮은 일들을 자동화해주는 도구들이 필요하다.
( Grunt, Gulp 사용 )
Grunt : https://gruntjs.com/
Grunt: The JavaScript Task Runner
Why use a task runner? In one word: automation. The less work you have to do when performing repetitive tasks like minification, compilation, unit testing, linting, etc, the easier your job becomes. After you've configured it through a Gruntfile, a task ru
gruntjs.com
Gulp : https://gulpjs.com/
gulp.js
Individual backers Since 2013, gulp has been the toolkit of choice for developers and designers alike. Not only do we have communities who’ve relied on us since the beginning, but there’s also a constant flow of new users who find out how great their w
gulpjs.com
3. 웹 애플리케이션의 빠른 로딩 속도와 높은 성능
사용자들이 웹 사이트를 접근할 때 5초 이내로 웹 사이트가 표시되지 않으면 대부분의 사용자들은 해당 사이트를 벗어나거나 "이 사이트 왜 이렇게 느려" 라고 생각한다.
그래서 웹 사이트의 로딩 속도를 높이기 위해 많은 노력을 하는데 그중 대표적인 노력이 브라우저에서 서버로 요청하는 파일 숫자를 줄이는 것이다.
웹팩은 이러한 이유들로 등장하게 되었다.
📂 웹팩의 4가지 속성
웹팩의 빌드 과정을 이해하기 위해서는 웹팩의 4가지 속성에 관해 알고 있어야 한다. 4가지 속성은 다음과 같다.
1. entry 2. output 3. loader 4. plugin
이 4가지 속성에 대해 파헤쳐보자!
entry
entry는 웹팩으로 변환할 대상이 되는 파일의 경로이다.
// webpack.config.js
module.exports = {
entry: './src/index.js'
}
위 코드는 웹팩을 실행했을 때 src 폴더 밑의 index.js을 대상으로 웹팩이 빌드를 한다는 뜻이다.
또한 위 코드처럼 엔트리 포인트가 하나인 경우도 있지만 entry 속성을 설정하여 여러 엔트리 포인트로 지정할 수 있다.
entry: {
login: './src/LoginView.js',
main: './src/MainView.js'
}
위와 같이 엔트리 포인트를 분리할 수 있는데 이 경우는 SPA이 아닌 특정 페이지로 진입했을 때 서버에서 해당 정보를 내려주는 형태의 MPA에 적합하다.
output
output은 웹팩을 돌리고 난 결과물의 파일 경로를 의미한다.
// webpack.config.js
var path = require('path');
module.exports = {
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, './dist')
}
}
최소한 filename 은 지정해줘야 하며 일반적으로 path 속성을 함께 정의한다.
위 코드는 dist라는 폴더 안에 bundel.js 파일로 저장하겠다 라는 것을 의미한다.
또한 output 파일 이름은 여러 가지 옵션을 넣을 수도 있는데,
// 결과 파일 이름에 entry 속성을 포함하는 옵션
module.exports = {
output: {
filename: '[name].bundle.js'
}
};
// 결과 파일 이름에 웹팩 내부적으로 사용하는 모듈 ID를 포함하는 옵션
module.exports = {
output: {
filename: '[id].bundle.js'
}
};
// 매 빌드시 마다 고유 해시 값을 붙이는 옵션
module.exports = {
output: {
filename: '[name].[hash].bundle.js'
}
};
// 웹팩의 각 모듈 내용을 기준으로 생생된 해시 값을 붙이는 옵션
module.exports = {
output: {
filename: '[chunkhash].bundle.js'
}
};
이런 식으로 생성된 결과 파일의 이름에는 각각 entry이름, 모듈, 아이디, 해시 값 등이 포함된다.
설정 가능한 더 많은 옵션은 https://webpack.kr/configuration/output 에서 볼 수 있다.
loader
loader는 웹팩이 웹 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 자원(html, css, image, font)등을 변환할 수 있도록 도와주는 속성이다.
// webpack.config.js
module.exports = {
module: {
rules: []
}
}
entry와 output과는 다르게 module이라는 이름을 사용한다.
자주 사용하는 loader로는 css, babel, sass, file loader 등이 있는데 css-loader 만 적용한 코드를 보자면
$ npm i css-loader -D
css-loader를 설치 후 웹팩 설정 파일을 다음과 같이 바꿔주면 된다.
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
use: ['css-loader']
}
]
}
}
module 코드를 보면 rules 배열에 객체를 추가했는데, 각 개체에는 2개의 속성이 들어간다.
- test : loader를 적용할 파일 유형 (일반적으로 정규표현식 사용)
- use : 해당 파일에 적용할 로더 이름
순으로 작성하면 되고 위 코드는 해당 프로젝트의 모든 css파일에 대해 css 로더를 적용한다는 뜻이다.
loader를 여러 개 사용할 경우는 rules 배열에 loader 옵션을 추가하면 된다.
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' },
// ...
]
}
}
loader 적용 순서
한 파일에 관해 loader를 여러개 사용할 경우 loader가 적용되는 순서에 주의해야 한다.
기본적으로 오른쪽에서 왼쪽 순으로 적용이 된다.
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
위 코드를 보면 scss 파일에 세 개의 loader 적용되어 있는데, 순서는 다음과 같다.
scss 파일에 대해 sass-loader로 전처리 > css 파일로 변환 > 인라인 style 태그로 추가
이런 식으로 진행이 되기에 한 파일에 대해 여러 개의 loader를 적용하는 경우 순서가 중요하다.
plugin
plugin은 웹팩의 기본적인 동작에 추가적인 기능을 제공하는 속성이다.
loader와 비교하자면 loader는 파일을 해석하고 변환하는 과정에 관여하는 것이고, plugin은 해당 결과물의 형태를 바꾸는 역할이다.
// webpack.config.js
module.exports = {
plugins: []
}
plugin의 배열에는 생성자 함수로 생성한 객체 인스턴스만 추가될 수 있다.
// webpack.config.js
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin(),
new webpack.ProgressPlugin()
]
}
위 코드와 같이 필요한 plugin을 추가하면 되고 자주 사용하는 plugin은 https://webpack.kr/plugins 여기에서 확인할 수 있다.
종류가 엄청 많다!
이렇게 4가지 속성을 통해 웹팩이 이루어져 있고,
웹팩 버전 4부터 추가된 mode에 대해 알아보자.
웹팩 실행 모드 - mode
웹팩 설정을 정의할 때 아래 코드와 같이 mode 속성을 통해 웹팩의 실행 모드가 설정된다.
module.exports = {
mode: 'none',
entry: '',
// ...
}
실행 모드는 3가지가 있는데
- none : 모드 설정 안 함
- develoment : 개발 모드
- production : 배포 모드 (기본값)가 있고 설정하지 않을 경우에는 기본값이 production 모드로 설정된다.
웹팩으로 실제 웹 애플리케이션을 개발할 때에는 보통 2가지 케이스로 구분하여 작업한다.
1. 개발할 때 사용할 웹팩 설정
2. 개발이 끝나고 배포할 때 사용할 웹팩 설정
mode 변수에 따라 동작을 변경하려면 객체 대신 함수를 export 하면 된다.
var config = {
entry: './app.js',
//...
};
module.exports = (env, argv) => {
if (argv.mode === 'development') {
config.devtool = 'source-map';
}
if (argv.mode === 'production') {
//...
}
return config;
};
참조
'Web' 카테고리의 다른 글
브라우저 주소창에 google.com을 입력했을 때 어떤 일이 일어날까? (0) | 2023.01.20 |
---|---|
REST API 과 GraphQL API 어떤 차이가 있을까? (0) | 2023.01.12 |
[Web] HTTP (1) - HTTP의 개념, 특징 (1) | 2022.12.11 |