참고
웹팩 핸드북 웹팩 공식홈페이지 Serverless Webpack
Webpack
웹팩이란?
웹팩은 모듈 번들러로 웹 애플리케이션을 구성하는 자원(HTML, CSS, Javascript, Images 등)을 각각의 모듈로 보고 이를 조합해 병합된 하나의 결과물로 만드는 도구 중 하나이다.
웹팩에서의 모듈은 웹 애플리케이션을 구성하는 모든 자원을 의미하며 파일 하나하나가 모두 모듈이 된다. 많은 자원들을 하나의 파일로 병합 및 압축 해주는 동작을 모듈 번들링이라고 한다.
웹팩의 등장배경
- 파일 단위의 자바스크립트 모듈 관리
- 웹 개발 작업 자동화 도구
- 웹 애플리케이션의 빠른 로딩 속도와 높은 성능
웹팩의 주요 속성
entry
엔트리는 웹팩에서 웹 자원을 변환하기 위해 필요한 최초 진입점이자 자바스크립트 파일 경로이다.
1
2
3
module.exports = {
entry: "./src/index.js"
};
웹팩에서 위의 코드를 실행하면 src
폴더 밑의 index.js
을 대상으로 웹팩이 빌드를 수행한다.
output
아웃풋은 웹팩을 돌리고 난 결과물의 파일 경로다.
1
2
3
4
5
6
7
8
const path = require("path");
module.exports = {
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "./dist")
}
};
filename
은 웹팩으로 빌드한 파일의 이름을, path
는 해당 파일의 경로를 의미한다.
Loader
로더는 웹팩이 애플리케이션을 해석할 때 자바스크립트 파일이 아닌 웹 자원(HTML, CSS, Images, Fonts 등)들을 변환할 수 있도록 도와준다.
1
2
3
4
5
6
7
8
9
10
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ["css-loader"]
}
]
}
};
test
는 로더를 적용할 파일 유형 (정규표현식 사용), use
는 해당 파일에 적용할 로더의 이름을 입력한다. 위의 코드는 해당 프로젝트의 모든 CSS파일에 대해 CSS 로더를 적용하겠다는 의미로 볼 수 있다.
plugin
플러그인은 웹팩의 기본적인 동작에 추가적인 기능을 제공한다. 로더는 파일을 해석하고 변환하는 과정에 관여하는 반면, 플러그인은 결과물의 형태를 바꾸는 역할을 한다.
1
2
3
4
5
const webpack = require("webpack");
module.exports = {
plugins: [new webpack.ProgressPlugin()]
};
플러그인 종류
- split-chunks-plugin
- clean-webpack-plugin
- image-webpack-loader
- webpack-bundle-analyzer-plugin
Developter Tools
Webpack Dev Server
웹팩 데브 서버는 웹 애플리케이션을 개발하는 과정에서 유용하게 쓸 수 있다. 웹팩의 빌드 대상 파일이 변경되었을 때 매번 웹팩 명령어를 실행하지 않아도 코드만 변경하고 저자하면 웹팩으로 빌드한 후 브라우저를 새로 고침해준다.
Source Map
소스맵은 배포용으로 빌드한 파일과 원본 파일을 서로 연결해준다. 압축해 배포한 파일에서 에러가 난다면 소스맵을 이용해 배포용 파일의 특정 부분이 원본 소스의 어떤 부분인지 확인할 수 있다.
Serverless Webpack
Serverless plugin to bundle your lambdas with Webpack
람다함수들을 웹팩으로 묶어주는 플러그인이다. 웹팩
은 여러 개의 모듈을 하나의 자바스크립트 코드로 압축하는 라이브러리다.
webpack configuration file
아래와 같이 webpack 경로를 따로 지정하지 않으면 webpack.config.js
를 찾는다.
1
2
3
4
5
6
7
custom:
webpack:
webpackConfig: ./src/my-webpack.config.js
includeModules: true
forceExclude:
- aws-sdk
1
2
3
4
5
6
7
8
9
10
11
12
13
// my-webpack.config.js
const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
const path = require("path");
module.exports = {
mode: slsw.lib.webpack.isLocal ? "development" : "production",
entry: slsw.lib.entries,
outputs: {
path: path.join(__dirname, ".webpack")
},
externals: [nodeExternals()]
};
- mode: 모드 (
production
,development
)에 따라 최적화 혹은 빠르게 빌드된다. - entry: webpack이 빌드할 파일의 시작위치를 나타낸다.
- output: 생성된 번들을 내보낼 위치와 파일이름을 지정한다.
- externals: 번들에서 제외할 모듈을 지정한다. 위의 코드는 외부모듈을 지정하고 있다.
실습
개발환경과 배포환경에서 빌드 목표가 달라 환경에 따라 webpack configuration을 분리하는 게 좋다. 중복된 부분이 많아 common
부분을 유지하면서 각각의 설정을 새로 생성했다. 이후, 설정을 합치기 위해 webpack-merge
를 사용한다.
webpack.common.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const path = require("path");
const nodeExternals = require("webpack-node-externals");
const webpack = require("webpack");
const slsw = require("serverless-webpack");
module.exports = {
entry: slsw.lib.entries,
output: {
libraryTarget: "commonjs",
path: path.resolve(__dirname, ".webpack"),
filename: "[name].js"
},
resolve: {
extensions: [".ts", ".js", ".json"]
},
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.ts$/,
use: ["ts-loader"]
}
]
},
target: "node"
};
common
에서 entry 와 output을 설정한다.
webpack.dev.js
1
2
3
4
5
6
7
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
module.exports = merge(common, {
mode: "development",
devtool: "source-map"
});
webpack.prod.js
1
2
3
4
5
6
const { merge } = require("webpack-merge");
const common = require("./webpack.common.js");
module.exports = merge(common, {
mode: "production"
});
환경에 맞게 mode
를 설정하고 development
환경에는 devtool 설정을 추가했다. webpack-merge를 사용해 common
을 중복해서 설정하지 않아도 된다.