metalsmith-optimize-images 0.9.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # metalsmith-optimize-images
2
2
 
3
- > **🚀 Release Candidate**: This plugin has achieved comprehensive test coverage (95.27%) and is ready for production testing. Recent critical bug fixes have resolved recursive processing and AVIF format issues. Feedback welcome before 1.0.0 release!
4
-
5
3
  Metalsmith plugin for generating responsive images with optimal formats
6
4
 
7
5
  [![metalsmith:plugin][metalsmith-badge]][metalsmith-url]
@@ -11,16 +9,18 @@ Metalsmith plugin for generating responsive images with optimal formats
11
9
  [![ESM/CommonJS][modules-badge]][npm-url]
12
10
  [![Known Vulnerabilities](https://snyk.io/test/npm/metalsmith-optimize-images/badge.svg)](https://snyk.io/test/npm/metalsmith-optimize-images)
13
11
 
12
+ > This Metalsmith plugin is under active development. The API is stable, but breaking changes may occur before reaching 1.0.0.
13
+
14
14
  ## Features
15
15
 
16
16
  - **Multiple image formats**: Generates AVIF and WebP variants with JPEG/PNG fallbacks
17
17
  - **Responsive sizes**: Creates different image sizes for various device widths
18
18
  - **Background image support**: Automatically processes unused images for CSS `image-set()` backgrounds
19
19
  - **Progressive loading**: Optional progressive image loading with low-quality placeholders
20
- - **Lazy loading**: Uses native browser lazy loading for better performance
20
+ - **Lazy loading**: Uses native browser lazy loading
21
21
  - **Content-based hashing**: Adds hash to filenames for optimal caching
22
22
  - **Layout shift prevention**: Adds width/height attributes
23
- - **Parallel processing**: Processes images in parallel for faster builds
23
+ - **Parallel processing**: Processes images in parallel
24
24
  - **Metadata generation**: Creates a JSON manifest with image information and variants
25
25
  - **Configurable compression**: Customize compression settings per format
26
26
  - **ESM and CommonJS support**:
@@ -33,20 +33,6 @@ Metalsmith plugin for generating responsive images with optimal formats
33
33
  npm install metalsmith-optimize-images
34
34
  ```
35
35
 
36
- ## Requirements
37
-
38
- - Node.js >=18.0.0
39
- - Metalsmith >=2.5.0
40
-
41
- ## Platform Testing Status
42
-
43
- - ✅ **macOS**: Fully tested and working
44
- - 🔄 **Windows**: Seeking community feedback on Sharp.js compatibility
45
- - 🔄 **Linux**: Seeking validation across different distributions
46
- - 🔄 **CI/CD**: Testing in various containerized environments
47
-
48
- **Help us reach 1.0.0**: If you test this plugin on Windows, Linux, or in production environments, please [share your experience](https://github.com/wernerglinka/metalsmith-optimize-images/issues)!
49
-
50
36
  ## Usage
51
37
 
52
38
  > This plugin **must** be run after assets are copied but before any final HTML processing.
@@ -228,7 +214,6 @@ After processing HTML-referenced images, the plugin:
228
214
  - **1x variant**: Half the original size for regular displays
229
215
  - **2x variant**: Original image size for retina displays (sharper on high-DPI screens)
230
216
  5. **Creates all formats** (AVIF, WebP, original) for optimal browser support
231
- 6. **No HTML replacement** - you manually write CSS with `image-set()`
232
217
 
233
218
  ### Using Background Images with CSS
234
219
 
@@ -284,10 +269,8 @@ metalsmith.use(
284
269
 
285
270
  - **Automatic format optimization** - Browser selects best supported format
286
271
  - **Retina display support** - 2x variants provide crisp images on high-DPI screens
287
- - **Smart sizing** - Uses actual image dimensions instead of arbitrary widths
288
272
  - **No manual work** - Plugin automatically finds and processes unused images in Metalsmith files object
289
273
  - **Consistent workflow** - Same formats and quality settings as HTML images
290
- - **Efficient processing** - Parallel processing of sizes and formats
291
274
 
292
275
  ## Progressive Loading
293
276
 
@@ -439,39 +422,19 @@ metalsmith.env('DEBUG', 'metalsmith-optimize-images*');
439
422
  }
440
423
  ```
441
424
 
442
- ## Recent Updates
443
-
444
- ### Bug Fixes (January 2025)
445
-
446
- - **🚫 Fixed Recursive Processing**: Resolved critical issue where the background image processor was finding already-generated responsive images and reprocessing them recursively, creating malformed filenames like `image-320w-640w-960w.jpg`
447
- - **🚫 Fixed HEIF Extension Issue**: Fixed Sharp.js AVIF processing that was sometimes generating `.heif` extensions instead of `.avif`
448
- - **✅ Enhanced Background Image Filtering**: Added comprehensive filtering to prevent responsive variants from being treated as source images
449
-
450
- ## Feedback & Testing
451
-
452
- This plugin is approaching 1.0.0 and we'd love your feedback! Please test and report:
453
-
454
- ### Especially Needed
455
-
456
- - **Windows compatibility**: Sharp.js native compilation and image processing
457
- - **Large image batches**: Performance with 50+ images
458
- - **Memory usage**: Resource consumption in your environment
459
- - **Cross-platform consistency**: Image quality and file sizes across platforms
460
- - **Progressive loading**: Behavior across different browsers
461
- - **Background image processing**: Testing the new `image-set()` feature with CSS backgrounds
425
+ ## License
462
426
 
463
- ### Current Status
427
+ MIT
464
428
 
465
- - 95.27% test coverage with comprehensive edge case handling
466
- - ✅ Real Metalsmith integration tests (no mocks)
467
- - ✅ Tested on macOS with Node.js 18+
468
- - 🔄 Seeking broader platform validation
429
+ ## Development transparency
469
430
 
470
- **Report issues or success stories**: [GitHub Issues](https://github.com/wernerglinka/metalsmith-optimize-images/issues)
431
+ Portions of this project were developed with the assistance of AI tools including Claude and Claude Code. These tools were used to:
471
432
 
472
- ## License
433
+ - Generate or refactor code
434
+ - Assist with documentation
435
+ - Troubleshoot bugs and explore alternative approaches
473
436
 
474
- MIT
437
+ All AI-assisted code has been reviewed and tested to ensure it meets project standards. See the included [CLAUDE.md](CLAUDE.md) file for more details.
475
438
 
476
439
  [npm-badge]: https://img.shields.io/npm/v/metalsmith-optimize-images.svg
477
440
  [npm-url]: https://www.npmjs.com/package/metalsmith-optimize-images
package/lib/index.cjs CHANGED
@@ -889,6 +889,12 @@ function replacePictureElement($, $img, variants, config) {
889
889
  */
890
890
  async function processHtmlFile(htmlFile, fileData, files, metalsmith, processedImages, debug, config) {
891
891
  debug(`Processing HTML file: ${htmlFile}`);
892
+
893
+ // Validate file.contents before processing
894
+ if (!fileData.contents || !Buffer.isBuffer(fileData.contents)) {
895
+ debug(`Skipping ${htmlFile}: invalid or missing file contents`);
896
+ return;
897
+ }
892
898
  const content = fileData.contents.toString();
893
899
 
894
900
  // Parse HTML
@@ -1118,33 +1124,8 @@ function injectProgressiveAssets($) {
1118
1124
  * Creates a responsive images plugin for Metalsmith
1119
1125
  * Generates multiple sizes and formats of images and replaces img tags with picture elements
1120
1126
  *
1121
- * @param {Object} options - Configuration options for the plugin
1122
- * @param {number[]} [options.widths] - Array of image widths to generate
1123
- * @param {string[]} [options.formats] - Array of image formats to generate (in order of preference)
1124
- * @param {Object} [options.formatOptions] - Format-specific compression settings
1125
- * @param {Object} [options.formatOptions.avif] - AVIF compression options
1126
- * @param {Object} [options.formatOptions.webp] - WebP compression options
1127
- * @param {Object} [options.formatOptions.jpeg] - JPEG compression options
1128
- * @param {Object} [options.formatOptions.png] - PNG compression options
1129
- * @param {string} [options.htmlPattern] - Glob pattern to match HTML files
1130
- * @param {string} [options.imgSelector] - CSS selector for images to process
1131
- * @param {string} [options.outputDir] - Output directory for processed images
1132
- * @param {string} [options.outputPattern] - Output naming pattern
1133
- * @param {boolean} [options.skipLarger] - Whether to skip generating sizes larger than original
1134
- * @param {boolean} [options.lazy] - Whether to add loading="lazy" to images
1135
- * @param {boolean} [options.dimensionAttributes] - Whether to add width/height attributes
1136
- * @param {string} [options.sizes] - Default sizes attribute
1137
- * @param {number} [options.concurrency] - Maximum number of images to process in parallel
1138
- * @param {boolean} [options.generateMetadata] - Whether to generate a metadata JSON file
1139
- * @param {boolean} [options.isProgressive] - Whether to use progressive image loading (default: true)
1140
- * @param {Object} [options.placeholder] - Placeholder image settings for progressive loading
1141
- * @param {number} [options.placeholder.width] - Placeholder image width (default: 50)
1142
- * @param {number} [options.placeholder.quality] - Placeholder image quality (default: 30)
1143
- * @param {number} [options.placeholder.blur] - Placeholder image blur amount (default: 10)
1144
- * @param {boolean} [options.processUnusedImages] - Whether to process unused images for background use (default: true)
1145
- * @param {string} [options.imagePattern] - Glob pattern to find images for background processing (default: `**\/*.{jpg,jpeg,png,gif,webp,avif}`)
1146
- * @param {string} [options.imageFolder] - Folder to scan for background images, relative to source (default: 'lib/assets/images')
1147
- * @return {Function} - Metalsmith plugin function
1127
+ * @param {Options} [options={}] - Configuration options for the plugin
1128
+ * @returns {import('metalsmith').Plugin} - Metalsmith plugin function
1148
1129
  */
1149
1130
  function optimizeImagesPlugin(options = {}) {
1150
1131
  // Build configuration with defaults and user options
@@ -1570,5 +1551,10 @@ function generateBackgroundVariantPath(originalPath, width, format, config) {
1570
1551
  return path__default["default"].join(config.outputDir, outputName);
1571
1552
  }
1572
1553
 
1554
+ // Set function name for better debugging
1555
+ Object.defineProperty(optimizeImagesPlugin, 'name', {
1556
+ value: 'metalsmith-optimize-images'
1557
+ });
1558
+
1573
1559
  module.exports = optimizeImagesPlugin;
1574
1560
  //# sourceMappingURL=index.cjs.map