webpack으로 번들링된 React 파일 hot deployment로 개발 빠르게 하기
개요
server 모듈은 nodemon으로 hot deployment가 쉽게 가능하지만, client 모듈은 추가 설정을 해주어야 한다.\
webpack-dev-server로 이용해서도 쉽게 가능하지만, React를 SSR로 연동한 이상, webpack-dev-server보다는 아래의 방법으로 하는것이 더 효과적이다.
선행과정
express로 SSR이 구현되어 있어야 한다.
설치
npm i -D webpack-dev-middleware
webpack-dev-middleware
express에서만 사용할 수 있는 개발용 미들웨어 있다. webpack으로 부터 번들링된 파일들일 사용할 수 있게 도와준다.
webpack-hot-middleware
webpack-dev-middleware와 항상 같이 쓰이고, webpack-dev-server 없이 hot reloading을 할 수 있도록 도와준다.
구현
webpack.client.js
- plugins에 wepback.HotModuleReplacementPlugin 을 추가한다.
- entry array에 webpack-hot-middleware/client를 추가한다.
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const hotMiddlewareScript = `webpack-hot-middleware/client?path=/__webpack_hmr&timeout=200&reload=true`
const webpack = require('webpack')
module.exports = {
entry: [hotMiddlewareScript, './src/client/index.js'],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, './dist'),
},
mode: 'development',
optimization: {
splitChunks: {
chunks: 'all',
},
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/env', '@babel/preset-react'],
plugins: ['@babel/plugin-proposal-class-properties'],
},
},
},
],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: 'src/index.html',
}),
],
}
server.js
webpack config 파일을 로드하고, webpack-dev-middleware와 webpack-hot-middleware를 추가한다.
import http from 'http'
import express from 'express'
import path from 'path'
import fs from 'fs'
const app = express()
const webpack = require('webpack')
const webpackConfig = require('../../webpack.client.js')
const webpackDevMiddleware = require('webpack-dev-middleware')
const webpackHotMiddleware = require('webpack-hot-middleware')
const compiler = webpack(webpackConfig)
app.use(webpackDevMiddleware(compiler))
app.use(webpackHotMiddleware(compiler))
const index = fs
.readFileSync(path.resolve(__dirname, '../dist/index.html'))
.toString()
app.use('/', express.static(path.resolve(__dirname, '../dist')))
app.get('*', (req, res) => {
res.send(index)
})
const server = new http.Server(app)
server.listen(3000, (err) => {
if (err) {
return console.error(err)
}
})