@lonik/oh-image 1.2.0 → 1.2.2
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 +26 -16
- package/dist/plugin.d.ts +0 -2
- package/dist/plugin.js +11 -10
- package/dist/react.d.ts +3 -1
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -1,30 +1,40 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Oh Image
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The missing `<Image />` component for Vite and React.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
For full documentation, visit [docs](https://lukonik.github.io/oh-image).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Installation
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install
|
|
10
|
+
npm install @lonik/oh-image sharp --save
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Usage
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
npm run play
|
|
17
|
-
```
|
|
15
|
+
### 1. Register the Vite plugin
|
|
18
16
|
|
|
19
|
-
|
|
17
|
+
```ts
|
|
18
|
+
// vite.config.ts
|
|
19
|
+
import { defineConfig } from "vite";
|
|
20
|
+
import react from "@vitejs/plugin-react";
|
|
21
|
+
import { ohImage } from "@lonik/oh-image/plugin";
|
|
20
22
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
export default defineConfig({
|
|
24
|
+
plugins: [react(), ohImage()],
|
|
25
|
+
});
|
|
23
26
|
```
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
### 2. Use the Image component
|
|
26
29
|
|
|
27
|
-
```
|
|
28
|
-
|
|
30
|
+
```tsx
|
|
31
|
+
import { Image } from "@lonik/oh-image/react";
|
|
32
|
+
import heroImg from "./hero.jpg?oh";
|
|
33
|
+
|
|
34
|
+
function App() {
|
|
35
|
+
return <Image src={heroImg} alt="Hero" />;
|
|
36
|
+
}
|
|
29
37
|
```
|
|
30
|
-
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
[MIT](./LICENSE)
|
package/dist/plugin.d.ts
CHANGED
|
@@ -14,8 +14,6 @@ interface ImageOptions {
|
|
|
14
14
|
height?: number | null;
|
|
15
15
|
/** Output format for the main image (e.g., 'webp', 'avif', 'png') */
|
|
16
16
|
format?: keyof FormatEnum | null;
|
|
17
|
-
/** Blur amount (true for default blur, or a number for sigma value) */
|
|
18
|
-
blur?: number | boolean;
|
|
19
17
|
/** Whether to generate a placeholder image for lazy loading */
|
|
20
18
|
placeholder?: boolean;
|
|
21
19
|
/** Breakpoints array - widths in pixels for responsive srcSet generation */
|
package/dist/plugin.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { basename, dirname, extname, join, parse } from "node:path";
|
|
2
|
-
import {
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
3
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
4
|
import queryString from "query-string";
|
|
5
5
|
import sharp from "sharp";
|
|
6
6
|
import pLimit from "p-limit";
|
|
7
7
|
|
|
8
8
|
//#region src/plugin/utils.ts
|
|
9
|
-
function
|
|
10
|
-
|
|
9
|
+
async function getFileHash(filePath) {
|
|
10
|
+
const content = await readFile(filePath);
|
|
11
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
11
12
|
}
|
|
12
13
|
async function readFileSafe(path) {
|
|
13
14
|
try {
|
|
@@ -79,7 +80,7 @@ const DEFAULT_CONFIGS = {
|
|
|
79
80
|
1920
|
|
80
81
|
],
|
|
81
82
|
format: "webp",
|
|
82
|
-
placeholder:
|
|
83
|
+
placeholder: true
|
|
83
84
|
};
|
|
84
85
|
const PROCESS_KEY = "oh";
|
|
85
86
|
const SUPPORTED_IMAGE_FORMATS = /\.(jpe?g|png|webp|avif|gif|svg)(\?.*)?$/i;
|
|
@@ -102,9 +103,8 @@ function ohImage(options) {
|
|
|
102
103
|
const fileId = basename(url);
|
|
103
104
|
return join(cacheDir, fileId);
|
|
104
105
|
}
|
|
105
|
-
function genIdentifier(uri, format, prefix) {
|
|
106
|
-
const
|
|
107
|
-
const uniqueFileId = `${prefix}-${getRandomString()}-${fileId}.${format}`;
|
|
106
|
+
function genIdentifier(uri, format, prefix, hash) {
|
|
107
|
+
const uniqueFileId = `${prefix}-${hash}-${basename(uri)}.${format}`;
|
|
108
108
|
if (!isBuild) return join(DEV_DIR, uniqueFileId);
|
|
109
109
|
return join(assetsDir, config.distDir, uniqueFileId);
|
|
110
110
|
}
|
|
@@ -150,11 +150,12 @@ function ohImage(options) {
|
|
|
150
150
|
const origin = parsed.path;
|
|
151
151
|
const { name, ext } = parse(parsed.path);
|
|
152
152
|
const metadata = await sharp(parsed.path).metadata();
|
|
153
|
+
const hash = await getFileHash(origin);
|
|
153
154
|
const mergedOptions = {
|
|
154
155
|
...config,
|
|
155
156
|
...parsed.options
|
|
156
157
|
};
|
|
157
|
-
const mainIdentifier = genIdentifier(name, mergedOptions.format ?? ext.slice(1), "main");
|
|
158
|
+
const mainIdentifier = genIdentifier(name, mergedOptions.format ?? ext.slice(1), "main", hash);
|
|
158
159
|
const mainEntry = {
|
|
159
160
|
width: mergedOptions.width,
|
|
160
161
|
height: mergedOptions.height,
|
|
@@ -178,7 +179,7 @@ function ohImage(options) {
|
|
|
178
179
|
placeholderWidth = Math.max(Math.round(metadata.width / metadata.height * PLACEHOLDER_IMG_SIZE), 1);
|
|
179
180
|
placeholderHeight = PLACEHOLDER_IMG_SIZE;
|
|
180
181
|
}
|
|
181
|
-
const placeholderIdentifier = genIdentifier(name, DEFAULT_IMAGE_FORMAT, "placeholder");
|
|
182
|
+
const placeholderIdentifier = genIdentifier(name, DEFAULT_IMAGE_FORMAT, "placeholder", hash);
|
|
182
183
|
const placeholderEntry = {
|
|
183
184
|
width: placeholderWidth,
|
|
184
185
|
height: placeholderHeight,
|
|
@@ -192,7 +193,7 @@ function ohImage(options) {
|
|
|
192
193
|
if (mergedOptions.bps) {
|
|
193
194
|
const srcSets = [];
|
|
194
195
|
for (const breakpoint of mergedOptions.bps) {
|
|
195
|
-
const srcSetIdentifier = genIdentifier(name, DEFAULT_IMAGE_FORMAT, `breakpoint-${breakpoint}
|
|
196
|
+
const srcSetIdentifier = genIdentifier(name, DEFAULT_IMAGE_FORMAT, `breakpoint-${breakpoint}`, hash);
|
|
196
197
|
const srcSetEntry = {
|
|
197
198
|
width: breakpoint,
|
|
198
199
|
format: DEFAULT_IMAGE_FORMAT,
|
package/dist/react.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ declare module "*?oh" {
|
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region src/react/types.d.ts
|
|
23
23
|
type ImageSrcType = string | ImageSrc;
|
|
24
|
-
interface ImageProps extends Partial<Pick<ImgHTMLAttributes<HTMLImageElement>, "
|
|
24
|
+
interface ImageProps extends Partial<Pick<ImgHTMLAttributes<HTMLImageElement>, "fetchPriority" | "decoding" | "loading" | "height" | "width" | "srcSet" | "className" | "sizes" | "style">> {
|
|
25
|
+
/** Alternative text for the image, required for accessibility. Use an empty string for decorative images. */
|
|
26
|
+
alt: string;
|
|
25
27
|
/** Configures the Image component to load the image immediately. */
|
|
26
28
|
asap?: boolean;
|
|
27
29
|
/** */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lonik/oh-image",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.2",
|
|
5
5
|
"description": "A React component library for optimized image handling.",
|
|
6
6
|
"author": "Luka Onikadze <lukonik@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
@@ -73,5 +73,14 @@
|
|
|
73
73
|
"dependencies": {
|
|
74
74
|
"p-limit": "^7.3.0",
|
|
75
75
|
"query-string": "^9.3.1"
|
|
76
|
-
}
|
|
76
|
+
},
|
|
77
|
+
"keywords": [
|
|
78
|
+
"react",
|
|
79
|
+
"reactjs",
|
|
80
|
+
"react-components",
|
|
81
|
+
"react-component-library",
|
|
82
|
+
"vite",
|
|
83
|
+
"vitejs",
|
|
84
|
+
"vite-plugin"
|
|
85
|
+
]
|
|
77
86
|
}
|