@@ -6,6 +6,7 @@ let sharp
6
6
try {
7
7
sharp = require ( 'sharp' )
8
8
} catch ( error ) {
9
+ // Note: This warning is shown before plugin instantiation, so silence option doesn't apply here
9
10
console . warn ( 'β οΈ Sharp not available. Default image generation will be disabled.' )
10
11
}
11
12
@@ -29,6 +30,7 @@ class WebpackImageSizesPlugin {
29
30
* @param {string } [options.defaultImageSource='src/img/static/default.jpg'] - Path to the source image for generating defaults
30
31
* @param {string } [options.defaultImagesOutputDir='dist/images'] - Directory where default images will be generated
31
32
* @param {string } [options.defaultImageFormat='jpg'] - Format for generated images (jpg, png, webp, avif)
33
+ * @param {boolean } [options.silence=false] - Whether to suppress console output
32
34
* @memberof WebpackImageSizesPlugin
33
35
*/
34
36
constructor ( options = { } ) {
@@ -42,10 +44,24 @@ class WebpackImageSizesPlugin {
42
44
defaultImageSource : options . defaultImageSource || 'src/img/static/default.jpg' ,
43
45
defaultImagesOutputDir : options . defaultImagesOutputDir || 'dist/images' ,
44
46
defaultImageFormat : options . defaultImageFormat || 'jpg' ,
47
+ silence : options . silence || false ,
45
48
...options ,
46
49
}
47
50
}
48
51
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
+
49
65
/**
50
66
* Applies the plugin to the webpack compiler.
51
67
* Sets up hooks for initial build and watch mode rebuilds.
@@ -61,7 +77,7 @@ class WebpackImageSizesPlugin {
61
77
const sizesPath = path . join ( confImgPath , this . options . sizesSubdir )
62
78
const tplPath = path . join ( confImgPath , this . options . tplSubdir )
63
79
64
- console . log ( 'π§ Starting WebpackImageSizesPlugin generation...' )
80
+ this . log ( 'log' , 'π§ Starting WebpackImageSizesPlugin generation...' )
65
81
66
82
// Check for deleted/renamed files if output files already exist
67
83
this . checkForDeletedFiles ( confImgPath , sizesPath , tplPath )
@@ -79,7 +95,7 @@ class WebpackImageSizesPlugin {
79
95
fs . writeFileSync ( imageLocationsPath , JSON . stringify ( imageLocations , null , 2 ) )
80
96
fs . writeFileSync ( imageSizesPath , JSON . stringify ( imageSizes , null , 2 ) )
81
97
82
- console . log ( `β
Generated ${ this . options . outputImageLocations } and ${ this . options . outputImageSizes } ` )
98
+ this . log ( 'log' , `β
Generated ${ this . options . outputImageLocations } and ${ this . options . outputImageSizes } ` )
83
99
84
100
// Generate default images if option is enabled
85
101
if ( this . options . generateDefaultImages ) {
@@ -90,7 +106,7 @@ class WebpackImageSizesPlugin {
90
106
callback ( )
91
107
}
92
108
} catch ( error ) {
93
- console . error ( 'β Error in WebpackImageSizesPlugin:' , error )
109
+ this . log ( 'error' , 'β Error in WebpackImageSizesPlugin:' , error )
94
110
if ( callback ) {
95
111
callback ( error )
96
112
}
@@ -102,7 +118,7 @@ class WebpackImageSizesPlugin {
102
118
103
119
// Hook for rebuilds in watch mode
104
120
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...' )
106
122
runGeneration ( null , callback )
107
123
} )
108
124
@@ -117,11 +133,11 @@ class WebpackImageSizesPlugin {
117
133
// Watch configuration directories
118
134
if ( fs . existsSync ( sizesPath ) ) {
119
135
compilation . contextDependencies . add ( sizesPath )
120
- console . log ( 'π Added sizes directory to watch dependencies' )
136
+ this . log ( 'log' , 'π Added sizes directory to watch dependencies' )
121
137
}
122
138
if ( fs . existsSync ( tplPath ) ) {
123
139
compilation . contextDependencies . add ( tplPath )
124
- console . log ( 'π Added tpl directory to watch dependencies' )
140
+ this . log ( 'log' , 'π Added tpl directory to watch dependencies' )
125
141
}
126
142
} )
127
143
} )
@@ -143,12 +159,12 @@ class WebpackImageSizesPlugin {
143
159
const allSizes = new Set ( ) // To avoid duplicates
144
160
145
161
if ( ! fs . existsSync ( sizesPath ) ) {
146
- console . warn ( `β οΈ Sizes directory not found: ${ sizesPath } ` )
162
+ this . log ( 'warn' , `β οΈ Sizes directory not found: ${ sizesPath } ` )
147
163
return imageSizes
148
164
}
149
165
150
166
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 ( ', ' ) } ` )
152
168
153
169
sizeFiles . forEach ( ( file ) => {
154
170
try {
@@ -170,14 +186,14 @@ class WebpackImageSizesPlugin {
170
186
}
171
187
} )
172
188
} catch ( error ) {
173
- console . error ( `β Error parsing ${ file } :` , error )
189
+ this . log ( 'error' , `β Error parsing ${ file } :` , error )
174
190
}
175
191
} )
176
192
177
193
// Extract additional sizes from TPL files that are not in JSON files
178
194
this . extractSizesFromTPLFiles ( tplPath , imageLocations , imageSizes [ 0 ] , allSizes )
179
195
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` )
181
197
return imageSizes
182
198
}
183
199
@@ -228,7 +244,7 @@ class WebpackImageSizesPlugin {
228
244
crop : true , // Default crop value for TPL-extracted sizes
229
245
}
230
246
231
- console . log ( `π¨ Added size from TPL: ${ sizeKey } ` )
247
+ this . log ( 'log' , `π¨ Added size from TPL: ${ sizeKey } ` )
232
248
}
233
249
}
234
250
} )
@@ -248,13 +264,13 @@ class WebpackImageSizesPlugin {
248
264
const processedFiles = new Set ( ) // For tracking processed files
249
265
250
266
if ( ! fs . existsSync ( sizesPath ) ) {
251
- console . warn ( `β οΈ Sizes directory not found: ${ sizesPath } ` )
267
+ this . log ( 'warn' , `β οΈ Sizes directory not found: ${ sizesPath } ` )
252
268
return imageLocations
253
269
}
254
270
255
271
// Process JSON files in sizes/ first
256
272
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 ( ', ' ) } ` )
258
274
259
275
sizeFiles . forEach ( ( file ) => {
260
276
try {
@@ -275,14 +291,14 @@ class WebpackImageSizesPlugin {
275
291
276
292
processedFiles . add ( filename )
277
293
} catch ( error ) {
278
- console . error ( `β Error parsing JSON ${ file } :` , error )
294
+ this . log ( 'error' , `β Error parsing JSON ${ file } :` , error )
279
295
}
280
296
} )
281
297
282
298
// Then process TPL files for unprocessed or missing files
283
299
if ( fs . existsSync ( tplPath ) ) {
284
300
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 ( ', ' ) } ` )
286
302
287
303
tplFiles . forEach ( ( file ) => {
288
304
try {
@@ -307,20 +323,20 @@ class WebpackImageSizesPlugin {
307
323
]
308
324
309
325
processedFiles . add ( filename )
310
- console . log ( `π Added location from TPL: ${ filename } ` )
326
+ this . log ( 'log' , `π Added location from TPL: ${ filename } ` )
311
327
}
312
328
} catch ( error ) {
313
- console . error ( `β Error parsing TPL ${ file } :` , error )
329
+ this . log ( 'error' , `β Error parsing TPL ${ file } :` , error )
314
330
}
315
331
} )
316
332
}
317
333
318
334
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)` )
320
336
321
337
// Log processed files for debugging
322
338
if ( processedFiles . size > 0 ) {
323
- console . log ( `β
Processed files: ${ Array . from ( processedFiles ) . join ( ', ' ) } ` )
339
+ this . log ( 'log' , `β
Processed files: ${ Array . from ( processedFiles ) . join ( ', ' ) } ` )
324
340
}
325
341
326
342
return imageLocations
@@ -335,15 +351,15 @@ class WebpackImageSizesPlugin {
335
351
*/
336
352
async generateDefaultImages ( compilerContext , imageSizes ) {
337
353
if ( ! sharp ) {
338
- console . warn ( 'β οΈ Sharp not available. Skipping default image generation.' )
354
+ this . log ( 'warn' , 'β οΈ Sharp not available. Skipping default image generation.' )
339
355
return
340
356
}
341
357
342
358
const sourceImagePath = path . resolve ( compilerContext , this . options . defaultImageSource )
343
359
const outputDir = path . resolve ( compilerContext , this . options . defaultImagesOutputDir )
344
360
345
361
if ( ! fs . existsSync ( sourceImagePath ) ) {
346
- console . warn ( `β οΈ Source image not found: ${ sourceImagePath } ` )
362
+ this . log ( 'warn' , `β οΈ Source image not found: ${ sourceImagePath } ` )
347
363
return
348
364
}
349
365
@@ -358,11 +374,12 @@ class WebpackImageSizesPlugin {
358
374
// Validate format
359
375
const supportedFormats = [ 'jpg' , 'jpeg' , 'png' , 'webp' , 'avif' ]
360
376
if ( ! supportedFormats . includes ( format ) ) {
361
- console . warn ( `β οΈ Unsupported format '${ format } '. Using 'jpg' instead.` )
377
+ this . log ( 'warn' , `β οΈ Unsupported format '${ format } '. Using 'jpg' instead.` )
362
378
this . options . defaultImageFormat = 'jpg'
363
379
}
364
380
365
- console . log (
381
+ this . log (
382
+ 'log' ,
366
383
`πΌοΈ Generating ${ sizeKeys . length } default images (${ format . toUpperCase ( ) } ) from ${
367
384
this . options . defaultImageSource
368
385
} `
@@ -396,14 +413,14 @@ class WebpackImageSizesPlugin {
396
413
const formatOptions = this . getFormatOptions ( this . options . defaultImageFormat )
397
414
await sharpInstance [ formatOptions . method ] ( formatOptions . options ) . toFile ( outputPath )
398
415
399
- console . log ( `β¨ Generated: ${ outputFilename } (${ width } x${ height } ${ size . crop ? ', cropped' : '' } )` )
416
+ this . log ( 'log' , `β¨ Generated: ${ outputFilename } (${ width } x${ height } ${ size . crop ? ', cropped' : '' } )` )
400
417
} catch ( error ) {
401
- console . error ( `β Error generating ${ outputFilename } :` , error . message )
418
+ this . log ( 'error' , `β Error generating ${ outputFilename } :` , error . message )
402
419
}
403
420
} )
404
421
405
422
await Promise . all ( promises )
406
- console . log ( `π Default image generation completed!` )
423
+ this . log ( 'log' , `π Default image generation completed!` )
407
424
}
408
425
409
426
/**
@@ -455,7 +472,7 @@ class WebpackImageSizesPlugin {
455
472
456
473
// Check if image-locations.json file already exists
457
474
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' )
459
476
return
460
477
}
461
478
@@ -485,23 +502,23 @@ class WebpackImageSizesPlugin {
485
502
const deletedFiles = existingEntries . filter ( ( entry ) => ! currentFiles . includes ( entry ) )
486
503
487
504
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' )
490
507
}
491
508
492
509
// Detect new files
493
510
const newFiles = currentFiles . filter ( ( file ) => ! existingEntries . includes ( file ) )
494
511
495
512
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' )
498
515
}
499
516
500
517
if ( deletedFiles . length === 0 && newFiles . length === 0 ) {
501
- console . log ( 'π No file changes detected' )
518
+ this . log ( 'log' , 'π No file changes detected' )
502
519
}
503
520
} 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 )
505
522
}
506
523
}
507
524
}
0 commit comments