React Native로 앱을 개발하면서 편리했던 기능중 하나는 hot reload라는 기능이였다. Native 앱은 수정사항이 생기면 앱 전체를 다시 빌드해야하는 수고스러움이 있다. 별거 아닌거 같아도 이러한 시간 소모는 이주 비효율 적이라고 생각한다. 이번에 NestJS로 mobile BFF를 만들기로 하고 이것저것 찾아보고 공부할때 webpack
라이브러리의 HMR
을 알게되었다. 이는 nestJS 애플리케이션의 변경사항이 있을 때, 그것만을 reload 시켜주는 기능이다.
이번 노트에서는 webpack
라이브러리의 HMR(Hot Module Relpacement)
에 대해 작성해 보려한다.
NestJS에서는 기본적으로 hot reload 기능인 watch
를 지원한다. 프로젝트 생성 후 package.json
파일에
"start: dev": "nest build --watch"
이라는 옵션이 정의되어 있는걸 볼 수 있을 것이다. 이 watch
옵션도 hot reload
를 해주는 기능이지만 watch
는 프로젝트 전체를 재시작 한다. 아는 작은 프로젝트의 경우 큰 문제가 되지않지만 프로젝트의 덩치가 점점 커지거나 bundle되는 파일이 많아질 수록 전체를 reloading 하는 것은 많은 병목을 유발하여 적합하지 않다.
HMR(Hot Module Replacement)
는 변경된 파일만 bundle하여 변경사항을 적용 시키는 방법이다.
그럼 webpack의 HMR(Hot Module Replacement)
가 뭔지부터 알아보자.
공식문서에는 다음과 같이 설명하고있다.
Hot Module Replacement(HMR)
는 모듈 전체를 다시 로드하지 않고 애플리케이션이 실행되는 동안 교환, 추가 또는 제거를 수행한다. 다음과 같은 방법으로 개발 속도를 크게 높일 수 있다.
- 전체 reload 중에 손실되는 애플리케이션의 상태를 유지한다.
- 변경된 사항만 갱신하여 개발시간을 절약한다.
- 소스코드에서 CSS/JS를 수정하면 브라우저에서 즉시 업데이트된다.
HMR
은 다음과 같이 동작한다.
- 애플리케이션은 HMR 런타임에 업데이트된 내용이 있는지 확인하도록 요청한다.
- 런타임에서 업데이트된 내용을 비동기적으로 다운로드받고 애플리케이션에게 알린다.
- 그런 후 애플리케이션은 런타임에 업데이트를 요청한다.
- 런타임은 업데이트를 동기적으로 적용한다.
$ npm i --save-dev webpack-node-externals run-script-webpack-plugin webpack
webpack-hmr.config.js
파일 생성 후 아래 코드 입력.const nodeExternals = require('webpack-node-externals');
const { RunScriptWebpackPlugin } = require('run-script-webpack-plugin');
module.exports = function (options, webpack) {
return {
...options,
entry: ['webpack/hot/poll?100', options.entry],
externals: [
nodeExternals({
allowlist: ['webpack/hot/poll?100'],
}),
],
plugins: [
... options.plugins,
new webpack.HotModuleReplacementPlugin(),
new webpack.WatchIgnorePlugin({
paths: [/\.js$/, /\.d\.ts$/],
}),
new RunScriptWebpackPlugin({ name: options.output,filename }),
],
};
};
HMR
을 활성화하기 위해 main.ts
파일에 아래 코드 추가.declare const module: any;
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
if (module.hot) {
module.hot.accept();
module.hot.dispose(() => app.close());
}
}
bootstrap();
package.json
파일 수정"start:dev": "nest build --webpack --webpackPath webpack-hmr.config.js --watch"
$ npm run start:dev