spark-html-image 0.1.1 → 0.1.3
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 +8 -9
- package/package.json +4 -5
- package/src/index.d.ts +3 -5
- package/src/index.js +20 -18
package/README.md
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
# ⚡ spark-html-image
|
|
2
2
|
|
|
3
3
|
Build-time image optimization for [spark-html](https://www.npmjs.com/package/spark-html)
|
|
4
|
-
sites — a
|
|
5
|
-
with a responsive `srcset`, **zero config**. No more
|
|
6
|
-
`scripts/optimize-images.js` wired into the build command.
|
|
4
|
+
sites — a `spark-html-bun` pipeline step that converts your `<img>` references
|
|
5
|
+
to **webp/avif** with a responsive `srcset`, **zero config**. No more
|
|
6
|
+
hand-written `scripts/optimize-images.js` wired into the build command.
|
|
7
7
|
|
|
8
8
|
```js
|
|
9
|
-
//
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import image from 'spark-html-image';
|
|
9
|
+
// spark.config.js
|
|
10
|
+
import prerender from 'spark-prerender/bun';
|
|
11
|
+
import image from 'spark-html-image/bun';
|
|
13
12
|
|
|
14
13
|
export default {
|
|
15
|
-
|
|
14
|
+
pipeline: [prerender(), image()],
|
|
16
15
|
};
|
|
17
16
|
```
|
|
18
17
|
|
|
@@ -84,6 +83,6 @@ virtual DOM, no build step required. Add only what you use.
|
|
|
84
83
|
| [`spark-html-manifest`](https://www.npmjs.com/package/spark-html-manifest) | PWA manifest + icons + head tags (and optional service worker) from one config. |
|
|
85
84
|
| [`spark-html-offline`](https://www.npmjs.com/package/spark-html-offline) | Offline URL imports — a service worker that caches CDN components. |
|
|
86
85
|
| [`spark-html-sri`](https://www.npmjs.com/package/spark-html-sri) | Subresource Integrity — hash + verify assets and remote components. |
|
|
87
|
-
| [`create-spark-html-app`](https://www.npmjs.com/package/create-spark-html-app) | Scaffold a
|
|
86
|
+
| [`create-spark-html-app`](https://www.npmjs.com/package/create-spark-html-app) | Scaffold a spark-html app in one command. |
|
|
88
87
|
| [`prettier-plugin-spark`](https://www.npmjs.com/package/prettier-plugin-spark) | Prettier for components — formats `<script>`/`<style>`, markup stays byte-for-byte. |
|
|
89
88
|
| [`spark-html-language-server`](https://www.npmjs.com/package/spark-html-language-server) | LSP — diagnostics, go-to-definition, prop autocomplete, hover docs. |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spark-html-image",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Build-time image optimization for spark-html sites — a
|
|
3
|
+
"version": "0.1.3",
|
|
4
|
+
"description": "Build-time image optimization for spark-html sites — a spark-html-bun build step that converts <img> references to webp/avif with responsive srcset, zero config.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
|
7
7
|
"types": "./src/index.d.ts",
|
|
@@ -11,8 +11,7 @@
|
|
|
11
11
|
"types": "./src/index.d.ts",
|
|
12
12
|
"default": "./src/index.js"
|
|
13
13
|
},
|
|
14
|
-
"./
|
|
15
|
-
"types": "./src/index.d.ts",
|
|
14
|
+
"./bun": {
|
|
16
15
|
"default": "./src/index.js"
|
|
17
16
|
}
|
|
18
17
|
},
|
|
@@ -33,7 +32,7 @@
|
|
|
33
32
|
},
|
|
34
33
|
"keywords": [
|
|
35
34
|
"spark-html",
|
|
36
|
-
"
|
|
35
|
+
"bun",
|
|
37
36
|
"images",
|
|
38
37
|
"webp",
|
|
39
38
|
"avif",
|
package/src/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* spark-html-image — build-time image optimization (
|
|
2
|
+
* spark-html-image — build-time image optimization (spark-html-bun step).
|
|
3
3
|
* Converts local raster <img> references in the built HTML (pages and
|
|
4
4
|
* component fragments) to webp/avif variants with a responsive srcset.
|
|
5
5
|
*/
|
|
@@ -19,10 +19,8 @@ export interface SparkImageOptions {
|
|
|
19
19
|
lazy?: boolean;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
/**
|
|
22
|
+
/** spark-html-bun pipeline step: optimize <img> references in the build output. */
|
|
23
23
|
export default function sparkImage(options?: SparkImageOptions): {
|
|
24
24
|
name: string;
|
|
25
|
-
|
|
26
|
-
configResolved(config: unknown): void;
|
|
27
|
-
closeBundle: { order: 'post'; handler(): Promise<void> };
|
|
25
|
+
run(ctx: { outDir: string }): Promise<void>;
|
|
28
26
|
};
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* spark-html-image — build-time image optimization for spark-html sites.
|
|
3
3
|
*
|
|
4
|
-
* A
|
|
4
|
+
* A build step: after the build (and after spark-prerender has written its
|
|
5
5
|
* per-route HTML), it scans every *.html in the out dir — pages AND
|
|
6
6
|
* components — for local raster <img> references, converts each to
|
|
7
7
|
* webp/avif at several widths with sharp, and rewrites the tag:
|
|
@@ -15,15 +15,16 @@
|
|
|
15
15
|
* The original file stays in place as the src fallback, so nothing breaks in
|
|
16
16
|
* a browser (or crawler) that ignores srcset. Zero config:
|
|
17
17
|
*
|
|
18
|
-
* //
|
|
18
|
+
* // spark.config.js
|
|
19
19
|
* import image from 'spark-html-image';
|
|
20
|
-
* export default {
|
|
20
|
+
* export default { pipeline: [prerender(), image()] };
|
|
21
21
|
*
|
|
22
22
|
* With `picture: true` it instead wraps the img in <picture> with one
|
|
23
23
|
* <source> per format (useful when you enable avif).
|
|
24
24
|
*
|
|
25
25
|
* No core involvement — this is the same pattern as spark-prerender:
|
|
26
|
-
* build-time only, optional, nothing added to the runtime.
|
|
26
|
+
* build-time only, optional, nothing added to the runtime. It's a
|
|
27
|
+
* spark-html-bun pipeline step: { name, run({ outDir }) }.
|
|
27
28
|
*/
|
|
28
29
|
import { join, dirname, extname, posix } from 'node:path';
|
|
29
30
|
import { readFile, writeFile, readdir, stat } from 'node:fs/promises';
|
|
@@ -84,19 +85,10 @@ export default function sparkImage(options = {}) {
|
|
|
84
85
|
const picture = options.picture === true;
|
|
85
86
|
const lazy = options.lazy !== false;
|
|
86
87
|
|
|
87
|
-
let outDir = 'dist';
|
|
88
|
-
|
|
89
88
|
return {
|
|
90
89
|
name: 'spark-html-image',
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
if (config && config.build && config.build.outDir) outDir = config.build.outDir;
|
|
94
|
-
},
|
|
95
|
-
// order:'post' → runs after spark-prerender's closeBundle has written the
|
|
96
|
-
// per-route HTML, so prerendered pages are rewritten too.
|
|
97
|
-
closeBundle: {
|
|
98
|
-
order: 'post',
|
|
99
|
-
async handler() {
|
|
90
|
+
// Put it after prerender() in the pipeline so per-route HTML is rewritten too.
|
|
91
|
+
async run({ outDir }) {
|
|
100
92
|
// sharp is imported lazily so merely having the plugin installed
|
|
101
93
|
// never loads the native module until a build actually runs.
|
|
102
94
|
let sharp;
|
|
@@ -121,7 +113,15 @@ export default function sparkImage(options = {}) {
|
|
|
121
113
|
let m = meta.get(file);
|
|
122
114
|
if (!m) {
|
|
123
115
|
const info = await sharp(file).metadata();
|
|
124
|
-
|
|
116
|
+
// EXIF orientations 5–8 display the image rotated 90° — the
|
|
117
|
+
// metadata reports the SENSOR dimensions, so swap to get the
|
|
118
|
+
// dimensions the page actually renders (and that the rotated
|
|
119
|
+
// variants below will have).
|
|
120
|
+
const swap = (info.orientation || 1) >= 5;
|
|
121
|
+
m = {
|
|
122
|
+
width: (swap ? info.height : info.width) || 0,
|
|
123
|
+
height: (swap ? info.width : info.height) || 0,
|
|
124
|
+
};
|
|
125
125
|
meta.set(file, m);
|
|
126
126
|
}
|
|
127
127
|
// Widths strictly below the intrinsic width, plus the intrinsic
|
|
@@ -138,7 +138,10 @@ export default function sparkImage(options = {}) {
|
|
|
138
138
|
const dest = destUrl.startsWith('/')
|
|
139
139
|
? join(root, destUrl.slice(1))
|
|
140
140
|
: join(dirname(file), posix.basename(destUrl));
|
|
141
|
-
|
|
141
|
+
// .rotate() with no args bakes the EXIF orientation into the
|
|
142
|
+
// pixels — webp/avif output drops the EXIF tag, so without
|
|
143
|
+
// this every phone photo would render sideways.
|
|
144
|
+
let img = sharp(file).rotate();
|
|
142
145
|
if (w) img = img.resize({ width: w });
|
|
143
146
|
await img[format]({ quality }).toFile(dest);
|
|
144
147
|
converted.set(key, url);
|
|
@@ -201,7 +204,6 @@ export default function sparkImage(options = {}) {
|
|
|
201
204
|
if (images) {
|
|
202
205
|
console.log(`[spark-html-image] optimized ${images} image reference(s) across ${files} file(s) (${formats.join('+')})`);
|
|
203
206
|
}
|
|
204
|
-
},
|
|
205
207
|
},
|
|
206
208
|
};
|
|
207
209
|
}
|