fastify-webpack-hot
v1.1.0
Published
A Fastify plugin for serving files emitted by Webpack with Hot Module Replacement (HMR).
Downloads
463
Readme
fastify-webpack-hot 🔥
A Fastify plugin for serving files emitted by Webpack with Hot Module Replacement (HMR).
Basic HMR Setup
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,
});
Examples
- TypeScript, Fastify and Webpack HRM example (uses Webpack Hot Module Replacement API)
- TypeScript, Fastify, Webpack and React HRM example (uses
ReactRefreshWebpackPlugin
)
Recipes
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,
})
Note: You may also try using fastify-compress
, however, beware of the outstanding issue that may cause the server to crash (fastify-compress#215).
Difference from webpack-dev-server
- Supports Hot Module Replacement.
- Does not allow to override default HTTP methods (GET, HEAD).
- Does not allow to provide custom headers.
- Does not allow to create an index.
- Does not support
serverSideRender
- Does not support
writeToDisk
- Does not support
MultiCompiler
- Does not support
Accept-Ranges
All of the above are relatively straightforward to implement, however, I didn't have a use-case for them. If you have a use-case, please raise a PR.
Troubleshooting
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.