A Fastify plugin for serving files emitted by Webpack with Hot Module Replacement (HMR)
fastify-webpack-hot ?
A Fastify plugin for serving files emitted by Webpack with Hot Module Replacement (HMR).
(fastify-webpack-hot
immediately propagates hot updates to the server and browser.)
Recipes
Basic HMR Setup
All you need to enable Webpack Hot Module Replacement is:
- Register
fastify-webpack-hot
Fastify plugin - Enable
HotModuleReplacementPlugin
Webpack plugin - Prepend
fastify-webpack-hot/client
entry script
Example:
import webpack from 'webpack';
import {
fastifyWebpackHot,
} from 'fastify-webpack-hot';
const compiler = webpack({
entry: [
'fastify-webpack-hot/client',
path.resolve(__dirname, '../app/main.js'),
],
mode: 'development',
plugins: [
new webpack.HotModuleReplacementPlugin(),
],
});
void app.register(fastifyWebpackHot, {
compiler,
});
For more thorough instructions, refer to the Project Setup Examples.
Accessing Webpack Stats
Stats instance is accessible under request.webpack.stats
:
app.get('*', async (request, reply) => {
const stats = request.webpack.stats.toJson({
all: false,
entrypoints: true,
});
// ...
);
The most common use case for accessing stats is for identifying and constructing the entrypoint assets, e.g.
for (const asset of stats.entrypoints?.main.assets ?? []) {
if (asset.name.endsWith('.js')) {
htmlBody +=
'<script defer="defer" src="/' + asset.name + '"></script>\n';
}
}
Accessing Output File System
You can access Output File System by referencing compiler.outputFileSystem
. However, this will have the type of OutputFileSystem
, which is incompatible with memfs
, which is used by this package. Therefore, a better way to access outputFileSystem
is by referencing request.webpack.outputFileSystem
:
app.get('*', async (request, reply) => {
const stats = JSON.parse(
await request.webpack.outputFileSystem.promises.readFile(
path.join(__dirname, '../dist/stats.json'),
'utf8'
)
);
// ...
);
This example shows how you would access stats.json
generated by webpack-stats-plugin
.
Note: You likely won't need to use this because fastify-webpack-hot
automatically detects which assets have been generated and serves them at output.publicPath
.
Compressing Response
This plugin is compatible with compression-webpack-plugin
, i.e. This plugin will serve compressed files if the following conditions are true:
- Your outputs include compressed file versions (either
.br
or.gz
) - Request includes a matching
accept-encoding
header
Example compression-webpack-plugin
configuration:
new CompressionPlugin({
algorithm: 'brotliCompress',
deleteOriginalAssets: false,
filename: '[path][base].br',
compressionOptions: {
level: zlib.constants.BROTLI_MIN_QUALITY,
},
minRatio: 0.8,
test: /\.(js|css|html|svg)$/,
threshold: 10_240,
})
Project Setup Examples
These are complete project setup examples that you can run locally to evaluate fastify-webpack-hot
plugin:
- TypeScript, Fastify and Webpack HRM example (uses Webpack Hot Module Replacement API)
- TypeScript, Fastify, Webpack and React HRM example (uses
ReactRefreshWebpackPlugin
)
Difference from webpack-dev-server
and webpack-hot-middleware
webpack-dev-server
and webpack-hot-middleware
were built for express framework and as such they require compatibility plugins to work with Fastify. Additionally, both libraries are being maintained with intent to support legacy webpack versions (all the way to webpack v1). As a result, they contain a lot of bloat that makes them slower and harder to maintain.
fastify-webpack-hot
is built from the ground up leveraging the latest APIs of Fastify and webpack, and it encompasses functionality of both libraries. It is faster and easier to maintain.
Troubleshooting
Browser Logging
This project uses roarr
logger to output the application's state.
In order to output logs in browser, you need to provide output interface. The easiest way of doing it is by including @roarr/browser-log-writer
in your project.
import '@roarr/browser-log-writer/init';
Afterwards, to output all logs set ROARR_LOG=true
in localStorage
:
localStorage.setItem('ROARR_LOG', 'true');
Note: Ensure that you have enabled verbose logs in DevTools to see all fastify-webpack-hot
logs.
Node.js Logging
This project uses roarr
logger to output the program's state.
Export ROARR_LOG=true
environment variable to enable log printing to stdout
.
Use roarr-cli
program to pretty-print the logs.