Skip to content

Commit bb1703a

Browse files
committed
feat (webpack-image-sizes-plugin): adds option to silence console output
Allows users to suppress console output from the plugin. This adds a `silence` option to the plugin configuration, which, when set to `true`, will prevent most console logs from being printed. This can be useful in environments where excessive logging is undesirable.
1 parent 1a0473a commit bb1703a

File tree

2 files changed

+51
-33
lines changed

2 files changed

+51
-33
lines changed

β€Žconfig/plugins.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ module.exports = {
4242
defaultImageSource: 'src/img/static/default.jpg', // Source image for generation
4343
defaultImagesOutputDir: 'dist/images', // Default images output directory
4444
defaultImageFormat: 'jpg', // Generated image format (jpg, png, webp, avif)
45+
silence: true, // Suppress console output
4546
}),
4647
]
4748

β€Žconfig/webpack-image-sizes-plugin.js

Lines changed: 50 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ let sharp
66
try {
77
sharp = require('sharp')
88
} catch (error) {
9+
// Note: This warning is shown before plugin instantiation, so silence option doesn't apply here
910
console.warn('⚠️ Sharp not available. Default image generation will be disabled.')
1011
}
1112

@@ -29,6 +30,7 @@ class WebpackImageSizesPlugin {
2930
* @param {string} [options.defaultImageSource='src/img/static/default.jpg'] - Path to the source image for generating defaults
3031
* @param {string} [options.defaultImagesOutputDir='dist/images'] - Directory where default images will be generated
3132
* @param {string} [options.defaultImageFormat='jpg'] - Format for generated images (jpg, png, webp, avif)
33+
* @param {boolean} [options.silence=false] - Whether to suppress console output
3234
* @memberof WebpackImageSizesPlugin
3335
*/
3436
constructor(options = {}) {
@@ -42,10 +44,24 @@ class WebpackImageSizesPlugin {
4244
defaultImageSource: options.defaultImageSource || 'src/img/static/default.jpg',
4345
defaultImagesOutputDir: options.defaultImagesOutputDir || 'dist/images',
4446
defaultImageFormat: options.defaultImageFormat || 'jpg',
47+
silence: options.silence || false,
4548
...options,
4649
}
4750
}
4851

52+
/**
53+
* Logs a message to the console if silence option is not enabled.
54+
*
55+
* @param {string} level - Log level ('log', 'warn', 'error')
56+
* @param {...any} args - Arguments to pass to console method
57+
* @memberof WebpackImageSizesPlugin
58+
*/
59+
log(level, ...args) {
60+
if (!this.options.silence) {
61+
console[level](...args)
62+
}
63+
}
64+
4965
/**
5066
* Applies the plugin to the webpack compiler.
5167
* Sets up hooks for initial build and watch mode rebuilds.
@@ -61,7 +77,7 @@ class WebpackImageSizesPlugin {
6177
const sizesPath = path.join(confImgPath, this.options.sizesSubdir)
6278
const tplPath = path.join(confImgPath, this.options.tplSubdir)
6379

64-
console.log('πŸ”§ Starting WebpackImageSizesPlugin generation...')
80+
this.log('log', 'πŸ”§ Starting WebpackImageSizesPlugin generation...')
6581

6682
// Check for deleted/renamed files if output files already exist
6783
this.checkForDeletedFiles(confImgPath, sizesPath, tplPath)
@@ -79,7 +95,7 @@ class WebpackImageSizesPlugin {
7995
fs.writeFileSync(imageLocationsPath, JSON.stringify(imageLocations, null, 2))
8096
fs.writeFileSync(imageSizesPath, JSON.stringify(imageSizes, null, 2))
8197

82-
console.log(`βœ… Generated ${this.options.outputImageLocations} and ${this.options.outputImageSizes}`)
98+
this.log('log', `βœ… Generated ${this.options.outputImageLocations} and ${this.options.outputImageSizes}`)
8399

84100
// Generate default images if option is enabled
85101
if (this.options.generateDefaultImages) {
@@ -90,7 +106,7 @@ class WebpackImageSizesPlugin {
90106
callback()
91107
}
92108
} catch (error) {
93-
console.error('❌ Error in WebpackImageSizesPlugin:', error)
109+
this.log('error', '❌ Error in WebpackImageSizesPlugin:', error)
94110
if (callback) {
95111
callback(error)
96112
}
@@ -102,7 +118,7 @@ class WebpackImageSizesPlugin {
102118

103119
// Hook for rebuilds in watch mode
104120
compiler.hooks.watchRun.tapAsync('WebpackImageSizesPlugin', (compiler, callback) => {
105-
console.log('πŸ‘€ Watch mode: checking for conf-img changes...')
121+
this.log('log', 'πŸ‘€ Watch mode: checking for conf-img changes...')
106122
runGeneration(null, callback)
107123
})
108124

@@ -117,11 +133,11 @@ class WebpackImageSizesPlugin {
117133
// Watch configuration directories
118134
if (fs.existsSync(sizesPath)) {
119135
compilation.contextDependencies.add(sizesPath)
120-
console.log('πŸ“ Added sizes directory to watch dependencies')
136+
this.log('log', 'πŸ“ Added sizes directory to watch dependencies')
121137
}
122138
if (fs.existsSync(tplPath)) {
123139
compilation.contextDependencies.add(tplPath)
124-
console.log('πŸ“ Added tpl directory to watch dependencies')
140+
this.log('log', 'πŸ“ Added tpl directory to watch dependencies')
125141
}
126142
})
127143
})
@@ -143,12 +159,12 @@ class WebpackImageSizesPlugin {
143159
const allSizes = new Set() // To avoid duplicates
144160

145161
if (!fs.existsSync(sizesPath)) {
146-
console.warn(`⚠️ Sizes directory not found: ${sizesPath}`)
162+
this.log('warn', `⚠️ Sizes directory not found: ${sizesPath}`)
147163
return imageSizes
148164
}
149165

150166
const sizeFiles = fs.readdirSync(sizesPath).filter((file) => file.endsWith('.json'))
151-
console.log(`πŸ“‹ Processing ${sizeFiles.length} size files: ${sizeFiles.join(', ')}`)
167+
this.log('log', `πŸ“‹ Processing ${sizeFiles.length} size files: ${sizeFiles.join(', ')}`)
152168

153169
sizeFiles.forEach((file) => {
154170
try {
@@ -170,14 +186,14 @@ class WebpackImageSizesPlugin {
170186
}
171187
})
172188
} catch (error) {
173-
console.error(`❌ Error parsing ${file}:`, error)
189+
this.log('error', `❌ Error parsing ${file}:`, error)
174190
}
175191
})
176192

177193
// Extract additional sizes from TPL files that are not in JSON files
178194
this.extractSizesFromTPLFiles(tplPath, imageLocations, imageSizes[0], allSizes)
179195

180-
console.log(`πŸ“ Generated ${Object.keys(imageSizes[0]).length} unique image sizes`)
196+
this.log('log', `πŸ“ Generated ${Object.keys(imageSizes[0]).length} unique image sizes`)
181197
return imageSizes
182198
}
183199

@@ -228,7 +244,7 @@ class WebpackImageSizesPlugin {
228244
crop: true, // Default crop value for TPL-extracted sizes
229245
}
230246

231-
console.log(`🎨 Added size from TPL: ${sizeKey}`)
247+
this.log('log', `🎨 Added size from TPL: ${sizeKey}`)
232248
}
233249
}
234250
})
@@ -248,13 +264,13 @@ class WebpackImageSizesPlugin {
248264
const processedFiles = new Set() // For tracking processed files
249265

250266
if (!fs.existsSync(sizesPath)) {
251-
console.warn(`⚠️ Sizes directory not found: ${sizesPath}`)
267+
this.log('warn', `⚠️ Sizes directory not found: ${sizesPath}`)
252268
return imageLocations
253269
}
254270

255271
// Process JSON files in sizes/ first
256272
const sizeFiles = fs.readdirSync(sizesPath).filter((file) => file.endsWith('.json'))
257-
console.log(`πŸ“‹ Processing ${sizeFiles.length} JSON files from sizes/: ${sizeFiles.join(', ')}`)
273+
this.log('log', `πŸ“‹ Processing ${sizeFiles.length} JSON files from sizes/: ${sizeFiles.join(', ')}`)
258274

259275
sizeFiles.forEach((file) => {
260276
try {
@@ -275,14 +291,14 @@ class WebpackImageSizesPlugin {
275291

276292
processedFiles.add(filename)
277293
} catch (error) {
278-
console.error(`❌ Error parsing JSON ${file}:`, error)
294+
this.log('error', `❌ Error parsing JSON ${file}:`, error)
279295
}
280296
})
281297

282298
// Then process TPL files for unprocessed or missing files
283299
if (fs.existsSync(tplPath)) {
284300
const tplFiles = fs.readdirSync(tplPath).filter((file) => file.endsWith('.tpl'))
285-
console.log(`πŸ“‹ Processing ${tplFiles.length} TPL files: ${tplFiles.join(', ')}`)
301+
this.log('log', `πŸ“‹ Processing ${tplFiles.length} TPL files: ${tplFiles.join(', ')}`)
286302

287303
tplFiles.forEach((file) => {
288304
try {
@@ -307,20 +323,20 @@ class WebpackImageSizesPlugin {
307323
]
308324

309325
processedFiles.add(filename)
310-
console.log(`πŸ“ Added location from TPL: ${filename}`)
326+
this.log('log', `πŸ“ Added location from TPL: ${filename}`)
311327
}
312328
} catch (error) {
313-
console.error(`❌ Error parsing TPL ${file}:`, error)
329+
this.log('error', `❌ Error parsing TPL ${file}:`, error)
314330
}
315331
})
316332
}
317333

318334
const totalEntries = Object.keys(imageLocations[0]).length
319-
console.log(`πŸ“ Generated ${totalEntries} image locations (${processedFiles.size} files processed)`)
335+
this.log('log', `πŸ“ Generated ${totalEntries} image locations (${processedFiles.size} files processed)`)
320336

321337
// Log processed files for debugging
322338
if (processedFiles.size > 0) {
323-
console.log(`βœ… Processed files: ${Array.from(processedFiles).join(', ')}`)
339+
this.log('log', `βœ… Processed files: ${Array.from(processedFiles).join(', ')}`)
324340
}
325341

326342
return imageLocations
@@ -335,15 +351,15 @@ class WebpackImageSizesPlugin {
335351
*/
336352
async generateDefaultImages(compilerContext, imageSizes) {
337353
if (!sharp) {
338-
console.warn('⚠️ Sharp not available. Skipping default image generation.')
354+
this.log('warn', '⚠️ Sharp not available. Skipping default image generation.')
339355
return
340356
}
341357

342358
const sourceImagePath = path.resolve(compilerContext, this.options.defaultImageSource)
343359
const outputDir = path.resolve(compilerContext, this.options.defaultImagesOutputDir)
344360

345361
if (!fs.existsSync(sourceImagePath)) {
346-
console.warn(`⚠️ Source image not found: ${sourceImagePath}`)
362+
this.log('warn', `⚠️ Source image not found: ${sourceImagePath}`)
347363
return
348364
}
349365

@@ -358,11 +374,12 @@ class WebpackImageSizesPlugin {
358374
// Validate format
359375
const supportedFormats = ['jpg', 'jpeg', 'png', 'webp', 'avif']
360376
if (!supportedFormats.includes(format)) {
361-
console.warn(`⚠️ Unsupported format '${format}'. Using 'jpg' instead.`)
377+
this.log('warn', `⚠️ Unsupported format '${format}'. Using 'jpg' instead.`)
362378
this.options.defaultImageFormat = 'jpg'
363379
}
364380

365-
console.log(
381+
this.log(
382+
'log',
366383
`πŸ–ΌοΈ Generating ${sizeKeys.length} default images (${format.toUpperCase()}) from ${
367384
this.options.defaultImageSource
368385
}`
@@ -396,14 +413,14 @@ class WebpackImageSizesPlugin {
396413
const formatOptions = this.getFormatOptions(this.options.defaultImageFormat)
397414
await sharpInstance[formatOptions.method](formatOptions.options).toFile(outputPath)
398415

399-
console.log(`✨ Generated: ${outputFilename} (${width}x${height}${size.crop ? ', cropped' : ''})`)
416+
this.log('log', `✨ Generated: ${outputFilename} (${width}x${height}${size.crop ? ', cropped' : ''})`)
400417
} catch (error) {
401-
console.error(`❌ Error generating ${outputFilename}:`, error.message)
418+
this.log('error', `❌ Error generating ${outputFilename}:`, error.message)
402419
}
403420
})
404421

405422
await Promise.all(promises)
406-
console.log(`πŸŽ‰ Default image generation completed!`)
423+
this.log('log', `πŸŽ‰ Default image generation completed!`)
407424
}
408425

409426
/**
@@ -455,7 +472,7 @@ class WebpackImageSizesPlugin {
455472

456473
// Check if image-locations.json file already exists
457474
if (!fs.existsSync(imageLocationsPath)) {
458-
console.log('πŸ“„ No existing image-locations.json found, creating fresh files')
475+
this.log('log', 'πŸ“„ No existing image-locations.json found, creating fresh files')
459476
return
460477
}
461478

@@ -485,23 +502,23 @@ class WebpackImageSizesPlugin {
485502
const deletedFiles = existingEntries.filter((entry) => !currentFiles.includes(entry))
486503

487504
if (deletedFiles.length > 0) {
488-
console.log(`πŸ—‘οΈ Detected ${deletedFiles.length} deleted/renamed files: ${deletedFiles.join(', ')}`)
489-
console.log(' β†’ These entries will be removed from generated files')
505+
this.log('log', `πŸ—‘οΈ Detected ${deletedFiles.length} deleted/renamed files: ${deletedFiles.join(', ')}`)
506+
this.log('log', ' β†’ These entries will be removed from generated files')
490507
}
491508

492509
// Detect new files
493510
const newFiles = currentFiles.filter((file) => !existingEntries.includes(file))
494511

495512
if (newFiles.length > 0) {
496-
console.log(`πŸ“‚ Detected ${newFiles.length} new files: ${newFiles.join(', ')}`)
497-
console.log(' β†’ These entries will be added to generated files')
513+
this.log('log', `πŸ“‚ Detected ${newFiles.length} new files: ${newFiles.join(', ')}`)
514+
this.log('log', ' β†’ These entries will be added to generated files')
498515
}
499516

500517
if (deletedFiles.length === 0 && newFiles.length === 0) {
501-
console.log('πŸ“‹ No file changes detected')
518+
this.log('log', 'πŸ“‹ No file changes detected')
502519
}
503520
} catch (error) {
504-
console.warn('⚠️ Could not read existing image-locations.json:', error.message)
521+
this.log('warn', '⚠️ Could not read existing image-locations.json:', error.message)
505522
}
506523
}
507524
}

0 commit comments

Comments
Β (0)