metalsmith-optimize-images 0.1.1
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/LICENSE +21 -0
- package/README.md +219 -0
- package/lib/index.cjs +612 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.js +583 -0
- package/lib/index.js.map +1 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Werner Glinka
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# metalsmith-optimize-images
|
|
2
|
+
|
|
3
|
+
> **⚠️: This plugin is a fully functional proof-of-concept. However, it is not yet fully tested and may contain bugs. Use with caution.**
|
|
4
|
+
|
|
5
|
+
Metalsmith plugin for generating responsive images with optimal formats
|
|
6
|
+
|
|
7
|
+
[![metalsmith:plugin][metalsmith-badge]][metalsmith-url]
|
|
8
|
+
[![npm: version][npm-badge]][npm-url]
|
|
9
|
+
[![license: MIT][license-badge]][license-url]
|
|
10
|
+
[![coverage][coverage-badge]][coverage-url]
|
|
11
|
+
[![ESM/CommonJS][modules-badge]][npm-url]
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- **Multiple image formats**: Generates AVIF and WebP variants with JPEG/PNG fallbacks
|
|
16
|
+
- **Responsive sizes**: Creates different image sizes for various device widths
|
|
17
|
+
- **Lazy loading**: Uses native browser lazy loading for better performance
|
|
18
|
+
- **Content-based hashing**: Adds hash to filenames for optimal caching
|
|
19
|
+
- **Layout shift prevention**: Adds width/height attributes
|
|
20
|
+
- **Parallel processing**: Processes images in parallel for faster builds
|
|
21
|
+
- **Metadata generation**: Creates a JSON file with image information
|
|
22
|
+
- **Configurable compression**: Customize compression settings per format
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npm install metalsmith-optimize-images
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Requirements
|
|
31
|
+
|
|
32
|
+
- Node.js 18.0.0 or newer
|
|
33
|
+
- Metalsmith 2.5.0 or newer
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
### ESM
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
import metalsmith from 'metalsmith';
|
|
41
|
+
import optimizeImages from 'metalsmith-optimize-images';
|
|
42
|
+
|
|
43
|
+
metalsmith.use(
|
|
44
|
+
optimizeImages({
|
|
45
|
+
// configuration options
|
|
46
|
+
widths: [320, 640, 960, 1280, 1920],
|
|
47
|
+
formats: ['avif', 'webp', 'original']
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### CommonJS
|
|
53
|
+
|
|
54
|
+
```javascript
|
|
55
|
+
const metalsmith = require('metalsmith');
|
|
56
|
+
const optimizeImages = require('metalsmith-optimize-images');
|
|
57
|
+
|
|
58
|
+
metalsmith.use(
|
|
59
|
+
optimizeImages({
|
|
60
|
+
// configuration options
|
|
61
|
+
widths: [320, 640, 960, 1280, 1920],
|
|
62
|
+
formats: ['avif', 'webp', 'original']
|
|
63
|
+
})
|
|
64
|
+
);
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Options
|
|
68
|
+
|
|
69
|
+
| Option | Type | Default | Description |
|
|
70
|
+
| --------------------- | ---------- | ------------------------------------- | ---------------------------------------- |
|
|
71
|
+
| `widths` | `number[]` | `[320, 640, 960, 1280, 1920]` | Image sizes to generate |
|
|
72
|
+
| `formats` | `string[]` | `['avif', 'webp', 'original']` | Image formats in order of preference |
|
|
73
|
+
| `formatOptions` | `object` | See below | Format-specific compression settings |
|
|
74
|
+
| `htmlPattern` | `string` | `**/*.html` | Glob pattern to match HTML files |
|
|
75
|
+
| `imgSelector` | `string` | `img:not([data-no-responsive])` | CSS selector for images to process |
|
|
76
|
+
| `outputDir` | `string` | `assets/images/responsive` | Where to store the responsive images |
|
|
77
|
+
| `outputPattern` | `string` | `[filename]-[width]w-[hash].[format]` | Filename pattern with tokens |
|
|
78
|
+
| `skipLarger` | `boolean` | `true` | Don't upscale images |
|
|
79
|
+
| `lazy` | `boolean` | `true` | Use native lazy loading |
|
|
80
|
+
| `dimensionAttributes` | `boolean` | `true` | Add width/height to prevent layout shift |
|
|
81
|
+
| `sizes` | `string` | `(max-width: 768px) 100vw, 75vw` | Default sizes attribute |
|
|
82
|
+
| `concurrency` | `number` | `5` | Process N images at a time |
|
|
83
|
+
| `generateMetadata` | `boolean` | `false` | Generate a metadata JSON file |
|
|
84
|
+
|
|
85
|
+
### Default Format Options
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
{
|
|
89
|
+
avif: { quality: 65, speed: 5 },
|
|
90
|
+
webp: { quality: 80, lossless: false },
|
|
91
|
+
jpeg: { quality: 85, progressive: true },
|
|
92
|
+
png: { compressionLevel: 8, palette: true }
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## How It Works
|
|
97
|
+
|
|
98
|
+
The plugin:
|
|
99
|
+
|
|
100
|
+
1. Scans HTML files for image tags
|
|
101
|
+
2. Processes each image to create multiple sizes and formats
|
|
102
|
+
3. Creates a content hash for each image for efficient caching
|
|
103
|
+
4. Replaces `<img>` tags with responsive `<picture>` elements
|
|
104
|
+
5. Adds width/height attributes to prevent layout shifts
|
|
105
|
+
6. Implements native lazy loading for better performance
|
|
106
|
+
|
|
107
|
+
## Examples
|
|
108
|
+
|
|
109
|
+
### Basic usage with defaults
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
metalsmith.use(optimizeImages());
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Custom configuration
|
|
116
|
+
|
|
117
|
+
```javascript
|
|
118
|
+
metalsmith.use(
|
|
119
|
+
optimizeImages({
|
|
120
|
+
// Generate fewer sizes
|
|
121
|
+
widths: [480, 960, 1920],
|
|
122
|
+
|
|
123
|
+
// Only use WebP and original format
|
|
124
|
+
formats: ['webp', 'original'],
|
|
125
|
+
|
|
126
|
+
// Custom quality settings
|
|
127
|
+
formatOptions: {
|
|
128
|
+
webp: { quality: 75, lossless: false },
|
|
129
|
+
jpeg: { quality: 80, progressive: true }
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
// Custom selector for specific images
|
|
133
|
+
imgSelector: 'img.responsive',
|
|
134
|
+
|
|
135
|
+
// Custom output directory
|
|
136
|
+
outputDir: 'images/processed',
|
|
137
|
+
|
|
138
|
+
// Don't add lazy loading
|
|
139
|
+
lazy: false
|
|
140
|
+
})
|
|
141
|
+
);
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Excluding specific images
|
|
145
|
+
|
|
146
|
+
Add the `data-no-responsive` attribute to any image you don't want processed:
|
|
147
|
+
|
|
148
|
+
```html
|
|
149
|
+
<img src="image.jpg" data-no-responsive alt="This image won't be processed" />
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Test Coverage
|
|
153
|
+
|
|
154
|
+
This project maintains a high level of test coverage to ensure reliability.
|
|
155
|
+
|
|
156
|
+
## Debug
|
|
157
|
+
|
|
158
|
+
For debugging, use Metalsmith's debug mode:
|
|
159
|
+
|
|
160
|
+
```javascript
|
|
161
|
+
// Enable debug output by setting the DEBUG environment variable
|
|
162
|
+
// DEBUG=metalsmith-responsive-images node build.js
|
|
163
|
+
|
|
164
|
+
const metalsmith = Metalsmith(__dirname).use(optimizeImages());
|
|
165
|
+
// other plugins...
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
You can also use the [metalsmith-debug](https://github.com/metalsmith/metalsmith-debug) plugin:
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
const debug = require('metalsmith-debug');
|
|
172
|
+
|
|
173
|
+
const metalsmith = Metalsmith(__dirname)
|
|
174
|
+
.use(debug()) // Add the metalsmith-debug plugin
|
|
175
|
+
.use(optimizeImages());
|
|
176
|
+
// other plugins...
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Or with the CLI:
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"plugins": {
|
|
184
|
+
"metalsmith-debug": true,
|
|
185
|
+
"metalsmith-optimize-images": {
|
|
186
|
+
"widths": [320, 640, 960, 1280, 1920]
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## CLI Usage
|
|
193
|
+
|
|
194
|
+
### Metalsmith CLI
|
|
195
|
+
|
|
196
|
+
```json
|
|
197
|
+
{
|
|
198
|
+
"plugins": {
|
|
199
|
+
"metalsmith-optimize-images": {
|
|
200
|
+
"widths": [320, 640, 960, 1280, 1920],
|
|
201
|
+
"formats": ["avif", "webp", "original"]
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## License
|
|
208
|
+
|
|
209
|
+
MIT
|
|
210
|
+
|
|
211
|
+
[npm-badge]: https://img.shields.io/npm/v/metalsmith-optimize-images.svg
|
|
212
|
+
[npm-url]: https://www.npmjs.com/package/metalsmith-optimize-images
|
|
213
|
+
[metalsmith-badge]: https://img.shields.io/badge/metalsmith-plugin-green.svg?longCache=true
|
|
214
|
+
[metalsmith-url]: https://metalsmith.io
|
|
215
|
+
[license-badge]: https://img.shields.io/github/license/wernerglinka/metalsmith-optimize-images
|
|
216
|
+
[license-url]: LICENSE
|
|
217
|
+
[coverage-badge]: https://img.shields.io/badge/test%20coverage-95%25-brightgreen
|
|
218
|
+
[coverage-url]: #test-coverage
|
|
219
|
+
[modules-badge]: https://img.shields.io/badge/modules-ESM%2FCJS-blue
|