devserver는 개발자를 위한 작은 express.js 서버이다.
이 서버가 해주는 역할은 간단하면서도 유용한데 예전엔 webapp을 만들면서 hot reload 혹은 빌드하고 결과를 보는 방식으로 webapp을 만들었다.
하지만 최근엔 예전 방식에서 탈피해 react-refresh-webpack-plugin을 사용해 메모리 상에 build 결과를 만들어 놓고 수정 후 수정된 부분만을 감지해 이를 이미 뿌려진 화면에 수정을 가하는 형태로 발전했다.
이는 다시 빌드하는 시간을 없애고 다시 해당 작업까지 진행을 기다리던 시간을 줄여주었다. 아니 없애버렸다.
설치는 아래 사이트에 이동해 설명을 잘 보고 설치하면 된다.
https://github.com/pmmmwh/react-refresh-webpack-plugin
설치하기 전에 문제점과 해결방안을 먼저 보시는걸 추천드린다.
그냥 위의 npm plugin을 다운받고 webpack.config에 plugin을 추가하는 형태로 설명을 안보고 그냥 휙휙 설치 끝! 하면 문제가 발생한다.
문제점은 바로 프로그램들의 버전이다.
위 링크를 타고 들어가면 최적의 버전을 선택할 수 있도록 table 형태로 표시되어 있다. 해당 버전에 맞게 npm을 설치하도록 하자.
npm을 특정 버전에 맞게 설치하는 방법은
npm i yourNpm@1.2.3
처럼 @를 붙이고 설치를 해주자. 본인이 호환성을 무시하고 막 설치를 하고 삽질을 하다 이 글을 적는다.
앞으로 어떤 npm을 설치할때 버전별 호환성을 무시하고 최신 버전으로 설치하면 큰 낭패를 볼 수 있다는 것을 기억하자.
아래는 @pmmmwh에서 권장하는 webpack.config 설정이다.
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const webpack = require('webpack');
// ... your other imports
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
// It is suggested to run both `react-refresh/babel` and the plugin in the `development` mode only,
// even though both of them have optimisations in place to do nothing in the `production` mode.
// If you would like to override Webpack's defaults for modes, you can also use the `none` mode -
// you then will need to set `forceEnable: true` in the plugin's options.
mode: isDevelopment ? 'development' : 'production',
module: {
rules: [
// ... other rules
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
// ... other loaders
{
loader: require.resolve('babel-loader'),
options: {
// ... other options
plugins: [
// ... other plugins
isDevelopment && require.resolve('react-refresh/babel'),
].filter(Boolean),
},
},
],
},
],
},
plugins: [
// ... other plugins
isDevelopment && new webpack.HotModuleReplacementPlugin(),
isDevelopment && new ReactRefreshWebpackPlugin(),
].filter(Boolean),
// ... other configuration options
};
With ts-loader
You need to install react-refresh-typescript and your TypeScript must be at least 4.0.
Emit module must be ESModule not CommonJS. You can overwrite it in ts-loader and still use CommonJS in your tsconfig file.
⚠ This package is maintained by the community not by Facebook.
# if you prefer npm
npm install -D react-refresh-typescript
# if you prefer yarn
yarn add -D react-refresh-typescript
# if you prefer pnpm
pnpm add -D react-refresh-typescript
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const webpack = require('webpack');
const ReactRefreshTypeScript = require('react-refresh-typescript');
// ... your other imports
const isDevelopment = process.env.NODE_ENV !== 'production';
module.exports = {
// It is suggested to run both `react-refresh-typescript` and the plugin in the `development` mode only,
// even though both of them have optimisations in place to do nothing in the `production` mode.
// If you would like to override Webpack's defaults for modes, you can also use the `none` mode -
// you then will need to set `forceEnable: true` in the plugin's options.
mode: isDevelopment ? 'development' : 'production',
module: {
rules: [
// ... other rules
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: [
// ... other loaders
{
loader: require.resolve('ts-loader'),
options: {
getCustomTransformers: () => ({
before: isDevelopment ? [ReactRefreshTypeScript()] : [],
}),
},
},
],
},
],
},
plugins: [
// ... other plugins
isDevelopment && new webpack.HotModuleReplacementPlugin(),
isDevelopment && new ReactRefreshWebpackPlugin(),
].filter(Boolean),
// ... other configuration options
};