I'm upgrading a project from Node.js v16 to v18. Because of that I also had to upgrade Webpack from version 4 to 5. Unfortunately, the offline-plugin is no longer supported in Webpack 5 so I had to find another way of configuring server worker, caching and managing offline functionality. I found that Workbox works well for my needs. However, I think I'm not configuring properly the workbox-webpack-plugin because when building the project I get the following error:
if (err) throw new _IconError["default"]("It was not possible to read '".concat(icon.src, "'."));
^
IconError: It was not possible to read '/app/images/icon.png'.
at Jimp.<anonymous> (/home/user/project/frontend/node_modules/webpack-pwa-manifest/dist/icons/index.js:128:22)
at Timeout._onTimeout (/home/user/project/frontend/node_modules/@jimp/core/src/index.js:222:9)
at listOnTimeout (node:internal/timers:569:17)
at processTimers (node:internal/timers:512:7)
I made sure the path to the image is correct and the name as well.
Here's my configuration:
module.exports = require('./webpack.base.babel')({
mode: 'production',
devtool: 'source-map',
plugins: [
new GenerateSW({ //That's the Workbox plugin
cacheId: 'main cache',
// Define the routes that should be precached
runtimeCaching: [
{
urlPattern: /\.(?:png|jpg|jpeg|webp|svg)$/,
handler: 'CacheFirst',
options: {
cacheName: 'images-cache',
expiration: {
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
},
},
},
{
urlPattern: /\.(?:js|css|html)$/,
handler: 'StaleWhileRevalidate',
},
],
}),
new WebpackPwaManifest({ \\The code throwing the error
name: 'React Boilerplate',
short_name: 'React BP',
description: 'My React Boilerplate-based project!',
background_color: '#fafafa',
theme_color: '#b1624d',
inject: true,
publicPath: '/app/images/',
ios: true,
icons: [
{
src: 'app/images/icon-512x512.png',
sizes: [72, 96, 128, 144, 192, 384, 512],
},
{
src: 'app/images/icon-512x512.png',
sizes: [120, 152, 167, 180],
ios: true,
},
],
}),
],
});
If anyone is familiar with how the configuration should look and sees anything that I missed or perhaps has suggestions for a different caching strategy that might solve the problem please let me know.
I also read about workbox-recipes, a plugin that has a function that handles image cache but I'm not sure how it works and if it's relevant to the case. Also for more context, it's probably worth mentioning that the project doesn't have many images and icons and they are static so I don't need a configuration that supports large amounts of often changing images.
Lastly, you may want to have a look at my service worker config:
import { precacheAndRoute } from 'workbox-precaching';
import { registerRoute } from 'workbox-routing';
import { CacheFirst, NetworkFirst, StaleWhileRevalidate } from 'workbox-strategies';
import { ExpirationPlugin } from 'workbox-expiration';
precacheAndRoute(self.__WB_MANIFEST);
registerRoute(
/\/api\/.*\//,
new NetworkFirst({
cacheName: 'api-cache',
})
);
registerRoute(
// Cache images using a CacheFirst strategy
/\.(png|jpg|jpeg|webp|gif)$/,
new CacheFirst({
cacheName: 'image-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 50,
maxAgeSeconds: 30 * 24 * 60 * 60,
}),
],
})
);
registerRoute(
({ event }) => event.request.mode === 'navigate',
new NetworkFirst({
cacheName: 'page-cache',
plugins: [
new ExpirationPlugin({
maxEntries: 10,
maxAgeSeconds: 30 * 24 * 60 * 60,
}),
],
})
);