@vitbokisch/next-optimized-images
Version:
Automatically optimize images used in next.js projects (jpeg, png, gif, svg).
1,024 lines (921 loc) • 28 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var module$1 = require('module');
var path = require('path');
var fs = require('fs');
var url = require('url');
var chalk = require('chalk');
var figures = require('figures');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
var chalk__default = /*#__PURE__*/_interopDefaultLegacy(chalk);
var figures__default = /*#__PURE__*/_interopDefaultLegacy(figures);
/**
* Enriches the next.js configuration object with default config values for
* next-optimized-iamges and returns it
*
* @param {object} nextConfig - next.js configuration object
* @returns {object} enriched config
*/
const getConfig = (nextConfig) => ({
optimizeImages: true,
optimizeImagesInDev: false,
handleImages: ['jpeg', 'png', 'svg', 'webp', 'gif'],
imagesFolder: 'images',
imagesName: '[name]-[hash].[ext]',
removeOriginalExtension: false,
inlineImageLimit: 8192,
defaultImageLoader: 'img-loader',
mozjpeg: {},
optipng: {},
pngquant: {},
gifsicle: {
interlaced: true,
optimizationLevel: 3,
},
svgo: {},
svgSpriteLoader: {
symbolId: '[name]-[hash:8]',
},
webp: {},
...nextConfig,
});
const __filename$1 = url.fileURLToPath((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('next-optimized-images.js.js', document.baseURI).href)));
/**
* Build options for the webpack file loader
*
* @param {object} nextConfig - next.js configuration
* @param {boolean} isServer - if the build is for the server
* @returns {object}
*/
const getFileLoaderOptions = (
{ assetPrefix, imagesPublicPath, imagesOutputPath, imagesFolder, imagesName },
isServer
) => {
let publicPath = `/_next/static/${imagesFolder}/`;
if (imagesPublicPath) {
publicPath = imagesPublicPath;
} else if (assetPrefix) {
publicPath = `${assetPrefix}${
assetPrefix.endsWith('/') ? '' : '/'
}_next/static/${imagesFolder}/`;
}
return {
publicPath,
outputPath:
imagesOutputPath || `${isServer ? '../' : ''}static/${imagesFolder}/`,
name: imagesName,
}
};
/**
* Get the file-loader path
*
* @returns {string}
*/
const getFileLoaderPath = () => {
const absolutePath = path__default["default"].resolve(
path__default["default"].dirname(__filename$1),
'..',
'..',
'node_modules',
'file-loader',
'dist',
'cjs.js'
);
if (fs__default["default"].existsSync(absolutePath)) {
return absolutePath
}
return 'file-loader'
};
/**
* Apply the file loader to the webpack configuration
*
* @param {object} webpackConfig - webpack configuration
* @param {object} nextConfig - next.js configuration
* @param {boolean} isServer - if the build is for the server
* @param {RegExp} fileRegex - regex for files to handle
* @returns {object}
*/
const applyFileLoader = (webpackConfig, nextConfig, isServer, fileRegex) => {
webpackConfig.module.rules.push({
test: fileRegex,
oneOf: [
{
use: {
loader: getFileLoaderPath(),
options: getFileLoaderOptions(nextConfig, isServer),
},
},
],
});
return webpackConfig
};
/**
* Build options for the webpack url loader
*
* @param {object} nextConfig - next.js configuration
* @param {boolean} isServer - if the build is for the server
* @returns {object}
*/
const getUrlLoaderOptions = ({ inlineImageLimit, ...config }, isServer) => ({
...getFileLoaderOptions(config, isServer),
limit: inlineImageLimit,
fallback: getFileLoaderPath(),
});
/**
* Build options for the webpack lqip loader
*
* @param {object} nextConfig - next.js configuration
* @param {boolean} isServer - if the build is for the server
* @returns {object}
*/
const getLqipLoaderOptions = (nextConfig, isServer) => ({
...getFileLoaderOptions(nextConfig, isServer),
...(nextConfig.lqip || {}),
});
const require$5 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('next-optimized-images.js.js', document.baseURI).href)));
/**
* Build options for the webpack responsive loader
*
* @param {object} nextConfig - next.js configuration
* @param {object} detectedLoaders - all detected and installed loaders
* @returns {object}
*/
const getResponsiveLoaderOptions = (
{ responsive, ...nextConfig },
isServer,
detectedLoaders
) => {
let adapter = responsive ? responsive.adapter : undefined;
if (!adapter && detectedLoaders.responsiveAdapter === 'sharp') {
adapter = require$5(`${detectedLoaders.responsive}${path__default["default"].sep}sharp`); // eslint-disable-line
}
return {
...getFileLoaderOptions(nextConfig, isServer),
name: '[name]-[width]-[hash].[ext]',
...(responsive || {}),
adapter,
}
};
/**
* Apply the responsive loader to the webpack configuration
*
* @param {object} webpackConfig - webpack configuration
* @param {object} nextConfig - next.js configuration
* @param {boolean} isServer - if the build is for the server
* @param {object} detectedLoaders - all detected and installed loaders
* @returns {object}
*/
const applyResponsiveLoader = (
webpackConfig,
nextConfig,
isServer,
detectedLoaders
) => {
webpackConfig.module.rules.push({
test: /\.(jpe?g|png)$/i,
oneOf: [
{
use: {
loader: 'responsive-loader',
options: getResponsiveLoaderOptions(
nextConfig,
isServer,
detectedLoaders
),
},
},
],
});
return webpackConfig
};
/**
* Build options for the webpack image trace loader
*
* @param {object} nextConfig - next.js configuration
* @returns {object}
*/
const getImageTraceLoaderOptions = ({ imageTrace }) => ({
...(imageTrace || {}),
});
const require$4 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('next-optimized-images.js.js', document.baseURI).href)));
/**
* Configure the common resource queries
*/
const queries = [
// ?url: force a file url/reference, never use inlining
{
test: 'url',
loaders: [getFileLoaderPath()],
optimize: true,
combinations: ['original'],
},
// ?inline: force inlining an image regardless of the defined limit
{
test: 'inline',
loaders: ['url-loader'],
options: [
{
limit: undefined,
},
],
optimize: true,
combinations: ['original'],
},
// ?include: include the image directly, no data uri or external file
{
test: 'include',
loaders: [
require$4.resolve('./loaders/raw-loader/export-loader.js'),
'raw-loader',
],
optimize: true,
combinations: ['original'],
},
// ?original: use the original image and don't optimize it
{
test: 'original',
loaders: ['url-loader'],
optimize: false,
},
// ?lqip: low quality image placeholder
{
test: 'lqip(&|$)',
loaders: [
require$4.resolve('./loaders/lqip-loader/picture-export-loader.js'),
'lqip-loader',
'url-loader',
],
optimize: false,
},
// ?lqip: low quality image placeholder
{
test: 'lqip-colors',
loaders: [
require$4.resolve('./loaders/lqip-loader/colors-export-loader.js'),
'lqip-loader',
'url-loader',
],
options: [
{},
{
base64: false,
palette: true,
},
],
optimize: false,
},
// ?resize: resize images
{
test: 'size',
loaders: ['responsive-loader'],
optimize: false,
},
// ?trace: generate svg image traces for placeholders
{
test: 'trace',
loaders: ['image-trace-loader', 'url-loader'],
optimize: true,
combinations: ['original'],
},
]
/**
* Add combinations
*/
;[].concat(queries).forEach((queryConfig) => {
if (queryConfig.combinations) {
queryConfig.combinations.forEach((combination) => {
if (combination === 'original') {
queries.unshift({
...queryConfig,
test: `(${queryConfig.test}.*original|original.*${queryConfig.test})`,
optimize: false,
});
}
});
}
});
/**
* Returns all common resource queries for the given optimization loader
*
* @param {object} nextConfig - next.js configuration object
* @param {boolean} isServer - if the current build is for a server
* @param {string} optimizerLoaderName - name of the loader used to optimize the images
* @param {object} optimizerLoaderOptions - config for the optimization loader
* @returns {array}
*/
const getResourceQueries = (
nextConfig,
isServer,
optimizerLoaderName,
optimizerLoaderOptions,
detectLoaders
) => {
const loaderOptions = {
'url-loader': getUrlLoaderOptions(nextConfig, isServer),
'file-loader': getFileLoaderOptions(nextConfig, isServer),
[getFileLoaderPath()]: getFileLoaderOptions(nextConfig, isServer),
'lqip-loader': getLqipLoaderOptions(nextConfig, isServer),
'responsive-loader': getResponsiveLoaderOptions(
nextConfig,
isServer,
detectLoaders
),
'image-trace-loader': getImageTraceLoaderOptions(nextConfig),
};
return queries.map((queryConfig) => {
const loaders = [];
queryConfig.loaders.forEach((loader, index) => {
const loaderConfig = {
loader,
};
if (loaderOptions[loader]) {
loaderConfig.options = loaderOptions[loader];
}
if (queryConfig.options) {
loaderConfig.options = {
...(loaderConfig.options || {}),
...(queryConfig.options[index] || {}),
};
}
loaders.push(loaderConfig);
});
return {
resourceQuery: new RegExp(queryConfig.test),
use: loaders.concat(
queryConfig.optimize && optimizerLoaderName !== null
? [
{
loader: optimizerLoaderName,
options: optimizerLoaderOptions,
},
]
: []
),
}
})
};
/**
* Build options for the webp loader
*
* @param {object} nextConfig - next.js configuration
* @returns {object}
*/
const getWebpLoaderOptions = ({ webp }) => webp || {};
/**
* Apply the webp loader to the webpack configuration
*
* @param {object} webpackConfig - webpack configuration
* @param {object} nextConfig - next.js configuration
* @param {boolean} optimize - if images should get optimized
* @param {boolean} isServer - if the build is for the server
* @param {object} detectedLoaders - all detected and installed loaders
* @returns {object}
*/
const applyWebpLoader = (
webpackConfig,
nextConfig,
optimize,
isServer,
detectLoaders
) => {
const webpLoaders = [
{
loader: 'url-loader',
options: getUrlLoaderOptions(nextConfig, isServer),
},
];
if (optimize) {
webpLoaders.push({
loader: 'webp-loader',
options: getWebpLoaderOptions(nextConfig),
});
}
webpackConfig.module.rules.push({
test: /\.webp$/i,
oneOf: [
// add all resource queries
...getResourceQueries(
nextConfig,
isServer,
!optimize ? null : 'webp-loader',
getWebpLoaderOptions(nextConfig),
detectLoaders
),
// default behavior: inline if below the definied limit, external file if above
{
use: webpLoaders,
},
],
});
return webpackConfig
};
/**
* Returns the resource query definition for converting a jpeg/png image to webp
*
* @param {object} nextConfig - next.js configuration
* @param {boolean} isServer - if the build is for the server
* @returns {object}
*/
const getWebpResourceQuery = (nextConfig, isServer) => {
const urlLoaderOptions = getUrlLoaderOptions(nextConfig, isServer);
const imageName =
urlLoaderOptions.name.indexOf('[ext]') >= 0
? urlLoaderOptions.name.replace(
'[ext]',
nextConfig.removeOriginalExtension ? 'webp' : '[ext].webp'
)
: `${urlLoaderOptions.name}.webp`;
return {
resourceQuery: /webp/,
use: [
{
loader: 'url-loader',
options: Object.assign({}, urlLoaderOptions, {
name: imageName,
mimetype: 'image/webp',
}),
},
{
loader: 'webp-loader',
options: getWebpLoaderOptions(nextConfig),
},
],
}
};
const require$3 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('next-optimized-images.js.js', document.baseURI).href)));
/**
* Returns the resource query definition for an svg sprite image
*
* @param {object} nextConfig - next.js configuration
* @param {object} detectedLoaders - detected loaders
* @param {object} imgLoaderOptions - img loader options
* @param {boolean} optimize - if the svg image should get optimized
* @returns {object}
*/
const getSvgSpriteLoaderResourceQuery = (
nextConfig,
detectedLoaders,
imgLoaderOptions,
optimize
) => ({
resourceQuery: /sprite/,
use: [
{
loader: 'svg-sprite-loader',
options: {
runtimeGenerator: require$3.resolve(
path__default["default"].resolve(__dirname, 'svg-runtime-generator.js')
),
...(nextConfig.svgSpriteLoader || {}),
},
},
].concat(
detectedLoaders.svg && optimize
? [
{
loader: 'img-loader',
options: imgLoaderOptions,
},
]
: []
),
});
const require$2 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('next-optimized-images.js.js', document.baseURI).href)));
/**
* Requires an imagemin plugin and configures it
*
* @param {string} plugin - plugin name
* @param {*} nextConfig - next.js configuration
* @return {function}
*/
const requireImageminPlugin = (plugin, nextConfig) => {
let moduleName = plugin;
if (nextConfig.overwriteImageLoaderPaths) {
moduleName = require$2.resolve(plugin, {
paths: [nextConfig.overwriteImageLoaderPaths],
});
}
console.log(moduleName);
/* eslint global-require: "off", import/no-dynamic-require: "off" */
return require$2(moduleName)(nextConfig[plugin.replace('imagemin-', '')] || {})
};
/**
* Build options for the img loader
*
* @param {object} nextConfig - next.js configuration
* @param {object} detectedLoaders - detected loaders
* @param {boolean} optimize - if images should get optimized
* @return {object}
*/
const getImgLoaderOptions = (nextConfig, detectedLoaders, optimize) => {
if (!optimize) {
return {
plugins: [],
}
}
return {
plugins: [
detectedLoaders.jpeg
? requireImageminPlugin(detectedLoaders.jpeg, nextConfig)
: undefined,
detectedLoaders.png
? requireImageminPlugin(detectedLoaders.png, nextConfig)
: undefined,
detectedLoaders.svg
? requireImageminPlugin(detectedLoaders.svg, nextConfig)
: undefined,
detectedLoaders.gif
? requireImageminPlugin(detectedLoaders.gif, nextConfig)
: undefined,
].filter(Boolean),
}
};
/**
* Build the regex for all handled image types
*
* @param {object} handledImageTypes - handled image types
* @return {RegExp}
*/
const getHandledFilesRegex = (handledImageTypes) => {
const handledFiles = [
handledImageTypes.jpeg ? 'jpe?g' : null,
handledImageTypes.png ? 'png' : null,
handledImageTypes.svg ? 'svg' : null,
handledImageTypes.gif ? 'gif' : null,
];
return new RegExp(`\\.(${handledFiles.filter(Boolean).join('|')})$`, 'i')
};
/**
* Apply the img loader to the webpack configuration
*
* @param {object} webpackConfig - webpack configuration
* @param {object} nextConfig - next.js configuration
* @param {boolean} optimize - if images should get optimized
* @param {boolean} isServer - if the build is for the server
* @param {object} detectedLoaders - detected loaders
* @param {object} handledImageTypes - detected image types
* @returns {object}
*/
const applyImgLoader = (
webpackConfig,
nextConfig,
optimize,
isServer,
detectedLoaders,
handledImageTypes
) => {
const imgLoaderOptions = getImgLoaderOptions(
nextConfig,
detectedLoaders,
optimize
);
webpackConfig.module.rules.push({
test: getHandledFilesRegex(handledImageTypes),
oneOf: [
// add all resource queries
...getResourceQueries(
nextConfig,
isServer,
optimize ? 'img-loader' : null,
imgLoaderOptions,
detectedLoaders
),
// ?webp: convert an image to webp
handledImageTypes.webp
? getWebpResourceQuery(nextConfig, isServer)
: undefined,
// ?sprite: add icon to sprite
detectedLoaders.svgSprite
? getSvgSpriteLoaderResourceQuery(
nextConfig,
detectedLoaders,
imgLoaderOptions,
optimize
)
: undefined,
// default behavior: inline if below the definied limit, external file if above
{
use: [
{
loader: 'url-loader',
options: getUrlLoaderOptions(nextConfig, isServer),
},
{
loader: 'img-loader',
options: imgLoaderOptions,
},
],
},
].filter(Boolean),
});
return webpackConfig
};
const require$1 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('next-optimized-images.js.js', document.baseURI).href)));
/**
* Checks if a node module is installed in the current context
*
* @param {string} name - module name
* @param {string} resolvePath - optional resolve path
* @returns {boolean}
*/
const isModuleInstalled = (name, resolvePath) => {
try {
require$1.resolve(name, resolvePath ? { paths: [resolvePath] } : undefined);
return true
} catch (e) {
return false
}
};
/**
* Detects all currently installed image optimization loaders
*
* @param {string} resolvePath - optional resolve path
* @returns {object}
*/
const detectLoaders = (resolvePath) => {
const jpeg = isModuleInstalled('imagemin-mozjpeg', resolvePath)
? 'imagemin-mozjpeg'
: false;
const gif = isModuleInstalled('imagemin-gifsicle', resolvePath)
? 'imagemin-gifsicle'
: false;
const svg = isModuleInstalled('imagemin-svgo', resolvePath)
? 'imagemin-svgo'
: false;
const svgSprite = isModuleInstalled('svg-sprite-loader', resolvePath)
? 'svg-sprite-loader'
: false;
const webp = isModuleInstalled('webp-loader', resolvePath)
? 'webp-loader'
: false;
const lqip = isModuleInstalled('lqip-loader', resolvePath)
? 'lqip-loader'
: false;
let png = false;
let responsive = false;
let responsiveAdapter = false;
if (isModuleInstalled('imagemin-optipng', resolvePath)) {
png = 'imagemin-optipng';
} else if (isModuleInstalled('imagemin-pngquant', resolvePath)) {
png = 'imagemin-pngquant';
}
if (isModuleInstalled('responsive-loader', resolvePath)) {
responsive = require$1
.resolve(
'responsive-loader',
resolvePath ? { paths: [resolvePath] } : undefined
)
.replace(/(\/|\\)lib(\/|\\)index.js$/g, '');
if (isModuleInstalled('sharp', resolvePath)) {
responsiveAdapter = 'sharp';
} else if (isModuleInstalled('jimp', resolvePath)) {
responsiveAdapter = 'jimp';
}
}
return {
jpeg,
gif,
svg,
svgSprite,
webp,
png,
lqip,
responsive,
responsiveAdapter,
}
};
/**
* Checks which image types should by handled by this plugin
*
* @param {object} nextConfig - next.js configuration object
* @returns {object}
*/
const getHandledImageTypes = (nextConfig) => {
const { handleImages } = nextConfig;
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,
}
};
/**
* Returns the number of image optimization loaders installed
*
* @param {object} loaders - detected loaders
* @returns {number}
*/
const getNumOptimizationLoadersInstalled = (loaders) =>
Object.values(loaders).filter(
(loader) =>
loader &&
(loader.startsWith('imagemin-') ||
loader.startsWith('webp-') ||
loader.startsWith('lqip-'))
).length;
/**
* Appends all loaders to the webpack configuration
*
* @param {object} webpackConfig - webpack configuration
* @param {object} nextConfig - next.js configuration
* @param {object} detectedLoaders - detected loaders
* @param {boolean} isServer - if the build is for the server
* @param {boolean} optimize - if images should get optimized or just copied
* @returns {object}
*/
const appendLoaders = (
webpackConfig,
nextConfig,
detectedLoaders,
isServer,
optimize
) => {
let config = webpackConfig;
const handledImageTypes = getHandledImageTypes(nextConfig);
let imgLoaderHandledTypes = handledImageTypes;
// check if responsive-loader should be the default loader and apply it if so
if (
nextConfig.defaultImageLoader &&
nextConfig.defaultImageLoader === 'responsive-loader'
) {
// img-loader no longer has to handle jpeg and png images
imgLoaderHandledTypes = {
...imgLoaderHandledTypes,
jpeg: false,
png: false,
};
config = applyResponsiveLoader(
webpackConfig,
nextConfig,
isServer,
detectLoaders
);
}
// apply img loader
const shouldApplyImgLoader =
imgLoaderHandledTypes.jpeg ||
imgLoaderHandledTypes.png ||
imgLoaderHandledTypes.gif ||
imgLoaderHandledTypes.svg;
if (
(detectedLoaders.jpeg ||
detectedLoaders.png ||
detectedLoaders.gif ||
detectedLoaders.svg) &&
shouldApplyImgLoader
) {
config = applyImgLoader(
webpackConfig,
nextConfig,
optimize,
isServer,
detectedLoaders,
imgLoaderHandledTypes
);
} else if (shouldApplyImgLoader) {
config = applyImgLoader(
webpackConfig,
nextConfig,
false,
isServer,
detectedLoaders,
imgLoaderHandledTypes
);
}
// apply webp loader
if (detectedLoaders.webp && handledImageTypes.webp) {
config = applyWebpLoader(
webpackConfig,
nextConfig,
optimize,
isServer,
detectLoaders
);
} else if (handledImageTypes.webp) {
config = applyWebpLoader(
webpackConfig,
nextConfig,
false,
isServer,
detectLoaders
);
}
// apply file loader for non optimizable image types
if (handledImageTypes.ico) {
config = applyFileLoader(webpackConfig, nextConfig, isServer, /\.(ico)$/i);
}
return config
};
const prefix = `${chalk__default["default"].gray('next-optimized-images')} ${chalk__default["default"].red(
figures__default["default"].pointer
)}`;
/**
* Output a warning when images should get optimized (prod build) but no optimization
* package is installed.
*/
const showWarning = () =>
console.log(
// eslint-disable-line no-console
`${prefix} ${chalk__default["default"].red('WARNING!')}
${prefix} ${chalk__default["default"].red('No package found which can optimize images.')}
${prefix} Starting from version ${chalk__default["default"].cyan('2')} of ${chalk__default["default"].cyan(
'next-optimized-images'
)}, all optimization is optional and you can choose which ones you want to use.
${prefix} For help during the setup and installation, please read ${chalk__default["default"].underline(
'https://github.com/cyrilwanner/next-optimized-images#optimization-packages'
)}
${prefix} If you recently ${chalk__default["default"].cyan(
'updated from v1 to v2'
)}, please read ${chalk__default["default"].underline(
'https://github.com/cyrilwanner/next-optimized-images/blob/master/UPGRADING.md'
)}
${prefix} If this is on purpose and you don't want this plugin to optimize the images, set the option ${chalk__default["default"].cyan(
'`optimizeImages: false`'
)} to hide this warning.
`
);
/**
* 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 = {}, nextComposePlugins = {}) => {
const { optimizeImages, optimizeImagesInDev, overwriteImageLoaderPaths } =
getConfig(nextConfig);
return Object.assign({}, 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 { dev, isServer } = options;
let enrichedConfig = config;
// detect all installed loaders
const detectedLoaders = detectLoaders(overwriteImageLoaderPaths);
// check if it should optimize images in the current step
const optimizeInCurrentStep =
nextComposePlugins && typeof nextComposePlugins.phase === 'string'
? (nextComposePlugins.phase === 'phase-production-build' &&
optimizeImages) ||
(nextComposePlugins.phase === 'phase-export' && optimizeImages) ||
(nextComposePlugins.phase === 'phase-development-server' &&
optimizeImagesInDev)
: (!dev && optimizeImages) || (dev && optimizeImagesInDev);
// show a warning if images should get optimized but no loader is installed
if (
optimizeImages &&
getNumOptimizationLoadersInstalled(detectedLoaders) === 0 &&
isServer
) {
showWarning();
}
// remove (unoptimized) builtin image processing introduced in next.js 9.2
if (enrichedConfig.module.rules) {
enrichedConfig.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)$/);
}
}
});
}
});
}
// append loaders
enrichedConfig = appendLoaders(
enrichedConfig,
getConfig(nextConfig),
detectedLoaders,
isServer,
optimizeInCurrentStep
);
if (typeof nextConfig.webpack === 'function') {
return nextConfig.webpack(enrichedConfig, options)
}
return enrichedConfig
},
})
};
exports["default"] = withOptimizedImages;
//# sourceMappingURL=next-optimized-images.js.js.map