UNPKG

@andreisergiu98/next-optimized-images

Version:

Automatically optimize images used in next.js projects (jpeg, png, gif, svg).

90 lines (76 loc) 3.39 kB
"use strict"; const getHandledImageTypes = handleImages => { return { jpeg: handleImages.indexOf('jpeg') >= 0 || handleImages.indexOf('jpg') >= 0, png: handleImages.indexOf('png') >= 0, svg: handleImages.indexOf('svg') >= 0, webp: handleImages.indexOf('webp') >= 0, gif: handleImages.indexOf('gif') >= 0, ico: handleImages.indexOf('ico') >= 0 }; }; const getHandledFilesRegex = handledImageTypes => { const handledFiles = [handledImageTypes.jpeg ? 'jpe?g' : null, handledImageTypes.png ? 'png' : null, handledImageTypes.svg ? 'svg' : null, handledImageTypes.gif ? 'gif' : null, handledImageTypes.webp ? 'webp' : null]; return new RegExp(`\\.(${handledFiles.filter(Boolean).join('|')})$`, 'i'); }; /** * Configure webpack and next.js to handle and optimize images with this plugin. * * @param {object} nextConfig - configuration, see the readme for possible values * @param {object} nextComposePlugins - additional information when loaded with next-compose-plugins * @returns {object} */ const withOptimizedImages = (nextConfig = {}) => { return { ...nextConfig, webpack(config, options) { if (!options.defaultLoaders) { throw new Error('This plugin is not compatible with Next.js versions below 5.0.0 https://err.sh/next-plugins/upgrade'); } const enrichedConfig = config; const handleImages = getHandledImageTypes(nextConfig.images && nextConfig.images.handleImages || ['jpeg', 'png', 'svg', 'webp', 'gif', 'ico']); // add optimized-images-loader enrichedConfig.module.rules.push({ test: getHandledFilesRegex(handleImages), use: [{ loader: 'optimized-images-loader', options: { outputPath: `static/images/`, publicPath: nextConfig.assetPrefix ? `${nextConfig.assetPrefix}${nextConfig.assetPrefix.endsWith('/') ? '' : '/'}_next/static/images/` : '/_next/static/images/', includeStrategy: 'react', ...(nextConfig.images || {}) } }] }); // add file-loader to handle ico files if (handleImages.ico) { enrichedConfig.module.rules.push({ test: /\.ico$/, use: [{ loader: 'file-loader', options: { outputPath: 'static/chunks/images/', publicPath: '/_next/static/chunks/images/', ...(nextConfig.images || {}) } }] }); } // remove (unoptimized) builtin image processing introduced in next.js 9.2 if (config.module.rules) { config.module.rules.forEach(rule => { if (rule.oneOf) { rule.oneOf.forEach(subRule => { if (subRule.issuer && !subRule.test && !subRule.include && subRule.exclude && subRule.use && subRule.use.options && subRule.use.options.name) { if ((String(subRule.issuer.test) === '/\\.(css|scss|sass)$/' || String(subRule.issuer) === '/\\.(css|scss|sass)$/') && subRule.use.options.name.startsWith('static/media/')) { subRule.exclude.push(/\.(jpg|jpeg|png|svg|webp|gif|ico)$/); } } }); } }); } if (typeof nextConfig.webpack === 'function') { return nextConfig.webpack(enrichedConfig, options); } return enrichedConfig; } }; }; module.exports = withOptimizedImages;