@son426/vite-image 0.1.7 → 0.1.8

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 CHANGED
@@ -21,3 +21,5 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  SOFTWARE.
22
22
 
23
23
 
24
+
25
+
package/README.md CHANGED
@@ -22,17 +22,26 @@ Simply add the plugin to your config, and start using the `<Image />` component
22
22
  Add it to `vite.config.ts`, and use it like this:
23
23
 
24
24
  ```tsx
25
+ // vite.config.ts
26
+ viteImage({
27
+ autoApply: {
28
+ extensions: [".jpg", ".png", ".webp"],
29
+ include: ["src/assets/**"],
30
+ },
31
+ });
32
+
33
+ // Component
25
34
  import Image from "@son426/vite-image/react";
26
- // 1. Import with the required query
27
- import myBg from "./assets/background.jpg?vite-image";
35
+ import myBg from "./assets/background.jpg"; // No query needed
28
36
 
29
37
  export default function Page() {
30
38
  return (
31
- // 2. Pass the object directly to src
32
39
  <Image
33
40
  src={myBg}
34
41
  alt="Optimized Background"
35
- fill // Optional: Fill parent container
42
+ fill
43
+ priority
44
+ placeholder="blur"
36
45
  />
37
46
  );
38
47
  }
@@ -40,7 +49,7 @@ export default function Page() {
40
49
 
41
50
  ## Installation
42
51
 
43
- Since `vite-imagetools` is handled internally, you only need to install this package.
52
+ Install the package. `vite-imagetools` and `@rollup/pluginutils` are included as dependencies.
44
53
 
45
54
  ```bash
46
55
  pnpm add @son426/vite-image
@@ -70,17 +79,65 @@ import { viteImage } from "@son426/vite-image/plugin";
70
79
 
71
80
  export default defineConfig({
72
81
  plugins: [
73
- // ... other plugins
74
- viteImage(),
82
+ viteImage(), // Default: breakpoints [640, 1024, 1920], no autoApply
75
83
  ],
76
84
  });
77
85
  ```
78
86
 
87
+ **Default configuration:**
88
+
89
+ - `breakpoints: [640, 1024, 1920]`
90
+ - `autoApply: undefined` (requires `?vite-image` query)
91
+
92
+ #### Configuration Options
93
+
94
+ **Custom breakpoints:**
95
+
96
+ ```typescript
97
+ viteImage({
98
+ breakpoints: [800, 1200, 1920],
99
+ });
100
+ ```
101
+
102
+ **Auto-apply without query string:**
103
+
104
+ ```typescript
105
+ viteImage({
106
+ autoApply: {
107
+ extensions: [".jpg", ".png", ".webp"],
108
+ include: ["src/assets/**"],
109
+ exclude: ["src/icons/**"],
110
+ },
111
+ });
112
+ ```
113
+
114
+ **Note**: `include` and `exclude` patterns are matched against actual image file paths (after alias resolution). For example, `@/assets/image.jpg` resolves to `src/assets/image.jpg`.
115
+
116
+ **With vite-imagetools options:**
117
+
118
+ ```typescript
119
+ viteImage({
120
+ breakpoints: [640, 1024, 1920],
121
+ autoApply: {
122
+ extensions: [".jpg", ".png"],
123
+ include: ["src/**"],
124
+ },
125
+ imagetools: {
126
+ // vite-imagetools options
127
+ defaultDirectives: (url) => {
128
+ if (url.searchParams.has("vite-image")) {
129
+ return new URLSearchParams("format=webp");
130
+ }
131
+ },
132
+ },
133
+ });
134
+ ```
135
+
79
136
  ### 2. Use the Component
80
137
 
81
- #### Using `?vite-image` query (Required)
138
+ #### Using `?vite-image` query
82
139
 
83
- The `?vite-image` query parameter is required and automatically generates all required image data. When using `?vite-image`, the `src` prop must be an object (not a string).
140
+ The `?vite-image` query parameter automatically generates all required image data. When using `?vite-image`, the `src` prop must be an object (not a string).
84
141
 
85
142
  ```typescript
86
143
  import Image from "@son426/vite-image/react";
@@ -91,9 +148,25 @@ function MyComponent() {
91
148
  }
92
149
  ```
93
150
 
94
- **Important**: When using `?vite-image`, the `src` prop must receive the imported object directly. String URLs are not supported for `?vite-image` imports.
151
+ **Without query string (autoApply enabled):**
152
+
153
+ ```typescript
154
+ // vite.config.ts
155
+ viteImage({
156
+ autoApply: {
157
+ extensions: [".jpg", ".png"],
158
+ include: ["src/assets/**"],
159
+ },
160
+ });
161
+
162
+ // Component
163
+ import bgImage from "@/assets/background.jpg"; // No query needed
164
+ <Image src={bgImage} alt="Background" />;
165
+ ```
166
+
167
+ **Important**: The `src` prop must receive the imported object directly. String URLs are not supported.
95
168
 
96
- The `?vite-image` query automatically generates:
169
+ The `?vite-image` query (or autoApply) automatically generates:
97
170
 
98
171
  - `src`: Optimized image URL
99
172
  - `srcSet`: Responsive srcSet string
@@ -182,7 +255,7 @@ import heroImage from "@/assets/hero.jpg?vite-image";
182
255
 
183
256
  | Prop | Type | Required | Default | Description |
184
257
  | ------------- | --------------------------------------------------------- | -------- | --------- | ----------------------------------------------------------------------- |
185
- | `src` | `ResponsiveImageData` | Yes | - | Image data object from `?vite-image` query |
258
+ | `src` | `ResponsiveImageData` | Yes | - | Image data object from `?vite-image` query or `autoApply` |
186
259
  | `fill` | `boolean` | No | `false` | Fill container mode (requires parent with `position: relative`) |
187
260
  | `sizes` | `string` | No | auto | Sizes attribute (auto-calculated from srcSet if not provided) |
188
261
  | `priority` | `boolean` | No | `false` | High priority loading (preload + eager + fetchPriority high) |
@@ -195,14 +268,14 @@ import heroImage from "@/assets/hero.jpg?vite-image";
195
268
 
196
269
  **Notes**:
197
270
 
198
- - The `src` prop must be an object imported from `?vite-image` query. String URLs are not supported.
271
+ - The `src` prop must be an object imported from `?vite-image` query or via `autoApply`. String URLs are not supported.
199
272
  - The `width` and `height` are automatically extracted from the `src` object.
200
273
  - When `priority={true}`, the image is preloaded using `react-dom`'s `preload` API and loaded with `loading="eager"` and `fetchPriority="high"`.
201
274
  - When `sizes` is not provided, it's automatically calculated from `srcSet` breakpoints.
202
275
 
203
276
  ### ResponsiveImageData
204
277
 
205
- The type returned from `?vite-image` query:
278
+ The type returned from `?vite-image` query or `autoApply`:
206
279
 
207
280
  ```typescript
208
281
  interface ResponsiveImageData {
@@ -225,10 +298,10 @@ import type { ImageProps, ResponsiveImageData } from "@son426/vite-image/react";
225
298
 
226
299
  ## How It Works
227
300
 
228
- 1. **`?vite-image` Query**: When you import an image with `?vite-image`, the plugin automatically generates:
301
+ 1. **Image Processing**: When you import an image with `?vite-image` query or via `autoApply`, the plugin automatically generates:
229
302
 
230
- - Responsive srcSet (640px, 1024px, 1920px widths)
231
- - Image metadata (1920px width)
303
+ - Responsive srcSet (default: 640px, 1024px, 1920px widths, customizable via `breakpoints`)
304
+ - Image metadata (largest breakpoint width)
232
305
  - Blur placeholder (20px width, blurred, low quality, inline base64 as `blurDataURL`)
233
306
 
234
307
  2. **Image Component**: The `<Image />` component handles:
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- export { ImageProps, ResponsiveImageData } from './react/index.js';
1
+ export { ImageProps } from './react/index.js';
2
+ export { A as AutoApplyConfig, R as ResponsiveImageData, V as ViteImageConfig } from './types-B08JIQxT.js';
2
3
  export { ViteImagePluginOptions, viteImage } from './plugin/index.js';
3
4
  import 'react/jsx-runtime';
4
5
  import 'react';
5
- import 'vite';
6
6
  import 'vite-imagetools';
7
+ import 'vite';
package/dist/index.js CHANGED
@@ -2,9 +2,64 @@ import 'react';
2
2
  import 'react-dom';
3
3
  import 'react/jsx-runtime';
4
4
  import { imagetools } from 'vite-imagetools';
5
+ import { createFilter } from '@rollup/pluginutils';
5
6
 
6
7
  // src/react/Image.tsx
7
- function viteImage(options) {
8
+ var DEFAULT_BREAKPOINTS = [640, 1024, 1920];
9
+ function getFileExtension(id) {
10
+ const [basePath] = id.split("?");
11
+ const match = basePath.match(/\.([^.]+)$/);
12
+ return match ? `.${match[1]}` : null;
13
+ }
14
+ function matchesExtension(id, extensions) {
15
+ if (!extensions || extensions.length === 0) return false;
16
+ const ext = getFileExtension(id);
17
+ if (!ext) return false;
18
+ return extensions.includes(ext);
19
+ }
20
+ function generateSrcSetParams(breakpoints) {
21
+ return `w=${breakpoints.join(";")}&format=webp&as=srcset`;
22
+ }
23
+ function generateMetaParams(breakpoints) {
24
+ const maxWidth = Math.max(...breakpoints);
25
+ return `w=${maxWidth}&format=webp&as=meta`;
26
+ }
27
+ function generateImageCode(basePath, breakpoints) {
28
+ const srcSetParams = generateSrcSetParams(breakpoints);
29
+ const metaParams = generateMetaParams(breakpoints);
30
+ const lqipParams = "w=20&blur=2&quality=20&format=webp&inline";
31
+ return `
32
+ import meta from "${basePath}?${metaParams}";
33
+ import srcSet from "${basePath}?${srcSetParams}";
34
+ import blurDataURL from "${basePath}?${lqipParams}";
35
+
36
+ export default {
37
+ src: meta.src,
38
+ width: meta.width,
39
+ height: meta.height,
40
+ srcSet: srcSet,
41
+ blurDataURL: blurDataURL
42
+ };
43
+ `;
44
+ }
45
+ function shouldAutoApply(id, autoApply, filter) {
46
+ if (!autoApply) return false;
47
+ if (!autoApply.extensions || autoApply.extensions.length === 0) {
48
+ return false;
49
+ }
50
+ if (!matchesExtension(id, autoApply.extensions)) {
51
+ return false;
52
+ }
53
+ if (filter && !filter(id)) {
54
+ return false;
55
+ }
56
+ return true;
57
+ }
58
+ function viteImage(config) {
59
+ const breakpoints = config?.breakpoints ?? DEFAULT_BREAKPOINTS;
60
+ const autoApply = config?.autoApply;
61
+ const imagetoolsOptions = config?.imagetools;
62
+ const filter = autoApply ? createFilter(autoApply.include, autoApply.exclude) : null;
8
63
  const viteImageMacro = {
9
64
  name: "vite-plugin-vite-image-macro",
10
65
  enforce: "pre",
@@ -12,27 +67,15 @@ function viteImage(options) {
12
67
  const [basePath, search] = id.split("?");
13
68
  const params = new URLSearchParams(search);
14
69
  if (params.has("vite-image")) {
15
- const srcSetParams = "w=640;1024;1920&format=webp&as=srcset";
16
- const metaParams = "w=1920&format=webp&as=meta";
17
- const lqipParams = "w=20&blur=2&quality=20&format=webp&inline";
18
- return `
19
- import srcSet from "${basePath}?${srcSetParams}";
20
- import meta from "${basePath}?${metaParams}";
21
- import blurDataURL from "${basePath}?${lqipParams}";
22
-
23
- export default {
24
- src: meta.src,
25
- width: meta.width,
26
- height: meta.height,
27
- srcSet: srcSet,
28
- blurDataURL: blurDataURL
29
- };
30
- `;
70
+ return generateImageCode(basePath, breakpoints);
71
+ }
72
+ if (shouldAutoApply(id, autoApply, filter)) {
73
+ return generateImageCode(basePath, breakpoints);
31
74
  }
32
75
  return null;
33
76
  }
34
77
  };
35
- return [viteImageMacro, imagetools(options)];
78
+ return [viteImageMacro, imagetools(imagetoolsOptions)];
36
79
  }
37
80
 
38
81
  export { viteImage };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugin/index.ts"],"names":[],"mappings":";;;;;;AAyBO,SAAS,UAAU,OAAA,EAAkD;AAE1E,EAAA,MAAM,cAAA,GAA+B;AAAA,IACnC,IAAA,EAAM,8BAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA,IACT,MAAM,KAAK,EAAA,EAAY;AACrB,MAAA,MAAM,CAAC,QAAA,EAAU,MAAM,CAAA,GAAI,EAAA,CAAG,MAAM,GAAG,CAAA;AACvC,MAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,MAAM,CAAA;AAEzC,MAAA,IAAI,MAAA,CAAO,GAAA,CAAI,YAAY,CAAA,EAAG;AAC5B,QAAA,MAAM,YAAA,GAAe,uCAAA;AACrB,QAAA,MAAM,UAAA,GAAa,4BAAA;AACnB,QAAA,MAAM,UAAA,GAAa,2CAAA;AAEnB,QAAA,OAAO;AAAA,8BAAA,EACiB,QAAQ,IAAI,YAAY,CAAA;AAAA,4BAAA,EAC1B,QAAQ,IAAI,UAAU,CAAA;AAAA,mCAAA,EACf,QAAQ,IAAI,UAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,CAAA;AAAA,MAUrD;AAEA,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,GACF;AAEA,EAAA,OAAO,CAAC,cAAA,EAAgB,UAAA,CAAW,OAAO,CAAC,CAAA;AAC7C","file":"index.js","sourcesContent":["import type { PluginOption } from \"vite\";\nimport { imagetools } from \"vite-imagetools\";\n\nexport type ViteImagePluginOptions = Parameters<typeof imagetools>[0];\n\n/**\n * Vite plugin for image optimization using vite-imagetools\n * This plugin handles ?vite-image queries and uses imagetools for image processing\n *\n * @param options - Options to pass to vite-imagetools\n * @returns Array of Vite plugins (vite-image macro and imagetools)\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { viteImage } from '@son426/vite-image/plugin';\n *\n * export default defineConfig({\n * plugins: [\n * ...viteImage(),\n * ],\n * });\n * ```\n */\nexport function viteImage(options?: ViteImagePluginOptions): PluginOption[] {\n // 커스텀 플러그인: ?vite-image 쿼리를 처리\n const viteImageMacro: PluginOption = {\n name: \"vite-plugin-vite-image-macro\",\n enforce: \"pre\" as const,\n async load(id: string) {\n const [basePath, search] = id.split(\"?\");\n const params = new URLSearchParams(search);\n\n if (params.has(\"vite-image\")) {\n const srcSetParams = \"w=640;1024;1920&format=webp&as=srcset\";\n const metaParams = \"w=1920&format=webp&as=meta\";\n const lqipParams = \"w=20&blur=2&quality=20&format=webp&inline\";\n\n return `\n import srcSet from \"${basePath}?${srcSetParams}\";\n import meta from \"${basePath}?${metaParams}\";\n import blurDataURL from \"${basePath}?${lqipParams}\";\n \n export default {\n src: meta.src,\n width: meta.width,\n height: meta.height,\n srcSet: srcSet,\n blurDataURL: blurDataURL\n };\n `;\n }\n\n return null;\n },\n };\n\n return [viteImageMacro, imagetools(options)];\n}\n"]}
1
+ {"version":3,"sources":["../src/plugin/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { PluginOption } from \"vite\";\nimport { imagetools } from \"vite-imagetools\";\nimport { createFilter } from \"@rollup/pluginutils\";\nimport type { ViteImageConfig, AutoApplyConfig } from \"../types\";\n\nexport type ViteImagePluginOptions = Parameters<typeof imagetools>[0];\n\n// Re-export types for convenience\nexport type { ViteImageConfig, AutoApplyConfig } from \"../types\";\n\n// Default configuration\nconst DEFAULT_BREAKPOINTS = [640, 1024, 1920];\n\n// Utility functions\nfunction getFileExtension(id: string): string | null {\n // 쿼리 파라미터 제거\n const [basePath] = id.split(\"?\");\n\n // 확장자 추출\n const match = basePath.match(/\\.([^.]+)$/);\n return match ? `.${match[1]}` : null;\n}\n\nfunction matchesExtension(id: string, extensions: string[]): boolean {\n if (!extensions || extensions.length === 0) return false;\n\n const ext = getFileExtension(id);\n if (!ext) return false;\n\n return extensions.includes(ext);\n}\n\nfunction generateSrcSetParams(breakpoints: number[]): string {\n return `w=${breakpoints.join(\";\")}&format=webp&as=srcset`;\n}\n\nfunction generateMetaParams(breakpoints: number[]): string {\n const maxWidth = Math.max(...breakpoints);\n return `w=${maxWidth}&format=webp&as=meta`;\n}\n\nfunction generateImageCode(basePath: string, breakpoints: number[]): string {\n const srcSetParams = generateSrcSetParams(breakpoints);\n const metaParams = generateMetaParams(breakpoints);\n const lqipParams = \"w=20&blur=2&quality=20&format=webp&inline\";\n\n // meta를 먼저 import하고, 그 다음에 srcSet과 blurDataURL을 import\n // 이렇게 하면 초기화 순서 문제를 방지할 수 있음\n return `\n import meta from \"${basePath}?${metaParams}\";\n import srcSet from \"${basePath}?${srcSetParams}\";\n import blurDataURL from \"${basePath}?${lqipParams}\";\n \n export default {\n src: meta.src,\n width: meta.width,\n height: meta.height,\n srcSet: srcSet,\n blurDataURL: blurDataURL\n };\n `;\n}\n\nfunction shouldAutoApply(\n id: string,\n autoApply: AutoApplyConfig | undefined,\n filter: ((id: string) => boolean) | null\n): boolean {\n // autoApply 설정이 없으면 false\n if (!autoApply) return false;\n\n // extensions가 없거나 빈 배열이면 false\n if (!autoApply.extensions || autoApply.extensions.length === 0) {\n return false;\n }\n\n // 확장자 매칭\n if (!matchesExtension(id, autoApply.extensions)) {\n return false;\n }\n\n // glob 패턴 매칭 (include/exclude)\n if (filter && !filter(id)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Vite plugin for image optimization using vite-imagetools\n * This plugin handles ?vite-image queries and uses imagetools for image processing\n *\n * @param config - Configuration options for vite-image plugin\n * @returns Array of Vite plugins (vite-image macro and imagetools)\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { viteImage } from '@son426/vite-image/plugin';\n *\n * export default defineConfig({\n * plugins: [\n * ...viteImage({\n * breakpoints: [640, 1024, 1920],\n * autoApply: {\n * extensions: ['.jpg', '.png'],\n * include: ['src/**'],\n * exclude: ['src/icons/**']\n * }\n * }),\n * ],\n * });\n * ```\n */\nexport function viteImage(config?: ViteImageConfig): PluginOption[] {\n // Config 병합\n const breakpoints = config?.breakpoints ?? DEFAULT_BREAKPOINTS;\n const autoApply = config?.autoApply;\n const imagetoolsOptions = config?.imagetools;\n\n // Glob 필터 생성 (autoApply가 있을 때만)\n const filter = autoApply\n ? createFilter(autoApply.include, autoApply.exclude)\n : null;\n\n // 커스텀 플러그인: ?vite-image 쿼리를 처리\n const viteImageMacro: PluginOption = {\n name: \"vite-plugin-vite-image-macro\",\n enforce: \"pre\" as const,\n async load(id: string) {\n const [basePath, search] = id.split(\"?\");\n const params = new URLSearchParams(search);\n\n // 1. 명시적 쿼리 체크 (기존 로직)\n if (params.has(\"vite-image\")) {\n return generateImageCode(basePath, breakpoints);\n }\n\n // 2. autoApply 체크\n if (shouldAutoApply(id, autoApply, filter)) {\n // ?vite-image 쿼리를 자동으로 추가하여 처리\n return generateImageCode(basePath, breakpoints);\n }\n\n return null;\n },\n };\n\n return [viteImageMacro, imagetools(imagetoolsOptions)];\n}\n"]}
@@ -1,12 +1,15 @@
1
1
  import { PluginOption } from 'vite';
2
2
  import { imagetools } from 'vite-imagetools';
3
+ import { V as ViteImageConfig } from '../types-B08JIQxT.js';
4
+ export { A as AutoApplyConfig } from '../types-B08JIQxT.js';
3
5
 
4
6
  type ViteImagePluginOptions = Parameters<typeof imagetools>[0];
7
+
5
8
  /**
6
9
  * Vite plugin for image optimization using vite-imagetools
7
10
  * This plugin handles ?vite-image queries and uses imagetools for image processing
8
11
  *
9
- * @param options - Options to pass to vite-imagetools
12
+ * @param config - Configuration options for vite-image plugin
10
13
  * @returns Array of Vite plugins (vite-image macro and imagetools)
11
14
  *
12
15
  * @example
@@ -17,11 +20,18 @@ type ViteImagePluginOptions = Parameters<typeof imagetools>[0];
17
20
  *
18
21
  * export default defineConfig({
19
22
  * plugins: [
20
- * ...viteImage(),
23
+ * ...viteImage({
24
+ * breakpoints: [640, 1024, 1920],
25
+ * autoApply: {
26
+ * extensions: ['.jpg', '.png'],
27
+ * include: ['src/**'],
28
+ * exclude: ['src/icons/**']
29
+ * }
30
+ * }),
21
31
  * ],
22
32
  * });
23
33
  * ```
24
34
  */
25
- declare function viteImage(options?: ViteImagePluginOptions): PluginOption[];
35
+ declare function viteImage(config?: ViteImageConfig): PluginOption[];
26
36
 
27
- export { type ViteImagePluginOptions, viteImage };
37
+ export { ViteImageConfig, type ViteImagePluginOptions, viteImage };
@@ -1,7 +1,62 @@
1
1
  import { imagetools } from 'vite-imagetools';
2
+ import { createFilter } from '@rollup/pluginutils';
2
3
 
3
4
  // src/plugin/index.ts
4
- function viteImage(options) {
5
+ var DEFAULT_BREAKPOINTS = [640, 1024, 1920];
6
+ function getFileExtension(id) {
7
+ const [basePath] = id.split("?");
8
+ const match = basePath.match(/\.([^.]+)$/);
9
+ return match ? `.${match[1]}` : null;
10
+ }
11
+ function matchesExtension(id, extensions) {
12
+ if (!extensions || extensions.length === 0) return false;
13
+ const ext = getFileExtension(id);
14
+ if (!ext) return false;
15
+ return extensions.includes(ext);
16
+ }
17
+ function generateSrcSetParams(breakpoints) {
18
+ return `w=${breakpoints.join(";")}&format=webp&as=srcset`;
19
+ }
20
+ function generateMetaParams(breakpoints) {
21
+ const maxWidth = Math.max(...breakpoints);
22
+ return `w=${maxWidth}&format=webp&as=meta`;
23
+ }
24
+ function generateImageCode(basePath, breakpoints) {
25
+ const srcSetParams = generateSrcSetParams(breakpoints);
26
+ const metaParams = generateMetaParams(breakpoints);
27
+ const lqipParams = "w=20&blur=2&quality=20&format=webp&inline";
28
+ return `
29
+ import meta from "${basePath}?${metaParams}";
30
+ import srcSet from "${basePath}?${srcSetParams}";
31
+ import blurDataURL from "${basePath}?${lqipParams}";
32
+
33
+ export default {
34
+ src: meta.src,
35
+ width: meta.width,
36
+ height: meta.height,
37
+ srcSet: srcSet,
38
+ blurDataURL: blurDataURL
39
+ };
40
+ `;
41
+ }
42
+ function shouldAutoApply(id, autoApply, filter) {
43
+ if (!autoApply) return false;
44
+ if (!autoApply.extensions || autoApply.extensions.length === 0) {
45
+ return false;
46
+ }
47
+ if (!matchesExtension(id, autoApply.extensions)) {
48
+ return false;
49
+ }
50
+ if (filter && !filter(id)) {
51
+ return false;
52
+ }
53
+ return true;
54
+ }
55
+ function viteImage(config) {
56
+ const breakpoints = config?.breakpoints ?? DEFAULT_BREAKPOINTS;
57
+ const autoApply = config?.autoApply;
58
+ const imagetoolsOptions = config?.imagetools;
59
+ const filter = autoApply ? createFilter(autoApply.include, autoApply.exclude) : null;
5
60
  const viteImageMacro = {
6
61
  name: "vite-plugin-vite-image-macro",
7
62
  enforce: "pre",
@@ -9,27 +64,15 @@ function viteImage(options) {
9
64
  const [basePath, search] = id.split("?");
10
65
  const params = new URLSearchParams(search);
11
66
  if (params.has("vite-image")) {
12
- const srcSetParams = "w=640;1024;1920&format=webp&as=srcset";
13
- const metaParams = "w=1920&format=webp&as=meta";
14
- const lqipParams = "w=20&blur=2&quality=20&format=webp&inline";
15
- return `
16
- import srcSet from "${basePath}?${srcSetParams}";
17
- import meta from "${basePath}?${metaParams}";
18
- import blurDataURL from "${basePath}?${lqipParams}";
19
-
20
- export default {
21
- src: meta.src,
22
- width: meta.width,
23
- height: meta.height,
24
- srcSet: srcSet,
25
- blurDataURL: blurDataURL
26
- };
27
- `;
67
+ return generateImageCode(basePath, breakpoints);
68
+ }
69
+ if (shouldAutoApply(id, autoApply, filter)) {
70
+ return generateImageCode(basePath, breakpoints);
28
71
  }
29
72
  return null;
30
73
  }
31
74
  };
32
- return [viteImageMacro, imagetools(options)];
75
+ return [viteImageMacro, imagetools(imagetoolsOptions)];
33
76
  }
34
77
 
35
78
  export { viteImage };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/plugin/index.ts"],"names":[],"mappings":";;;AAyBO,SAAS,UAAU,OAAA,EAAkD;AAE1E,EAAA,MAAM,cAAA,GAA+B;AAAA,IACnC,IAAA,EAAM,8BAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA,IACT,MAAM,KAAK,EAAA,EAAY;AACrB,MAAA,MAAM,CAAC,QAAA,EAAU,MAAM,CAAA,GAAI,EAAA,CAAG,MAAM,GAAG,CAAA;AACvC,MAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,MAAM,CAAA;AAEzC,MAAA,IAAI,MAAA,CAAO,GAAA,CAAI,YAAY,CAAA,EAAG;AAC5B,QAAA,MAAM,YAAA,GAAe,uCAAA;AACrB,QAAA,MAAM,UAAA,GAAa,4BAAA;AACnB,QAAA,MAAM,UAAA,GAAa,2CAAA;AAEnB,QAAA,OAAO;AAAA,8BAAA,EACiB,QAAQ,IAAI,YAAY,CAAA;AAAA,4BAAA,EAC1B,QAAQ,IAAI,UAAU,CAAA;AAAA,mCAAA,EACf,QAAQ,IAAI,UAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAAA,CAAA;AAAA,MAUrD;AAEA,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,GACF;AAEA,EAAA,OAAO,CAAC,cAAA,EAAgB,UAAA,CAAW,OAAO,CAAC,CAAA;AAC7C","file":"index.js","sourcesContent":["import type { PluginOption } from \"vite\";\nimport { imagetools } from \"vite-imagetools\";\n\nexport type ViteImagePluginOptions = Parameters<typeof imagetools>[0];\n\n/**\n * Vite plugin for image optimization using vite-imagetools\n * This plugin handles ?vite-image queries and uses imagetools for image processing\n *\n * @param options - Options to pass to vite-imagetools\n * @returns Array of Vite plugins (vite-image macro and imagetools)\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { viteImage } from '@son426/vite-image/plugin';\n *\n * export default defineConfig({\n * plugins: [\n * ...viteImage(),\n * ],\n * });\n * ```\n */\nexport function viteImage(options?: ViteImagePluginOptions): PluginOption[] {\n // 커스텀 플러그인: ?vite-image 쿼리를 처리\n const viteImageMacro: PluginOption = {\n name: \"vite-plugin-vite-image-macro\",\n enforce: \"pre\" as const,\n async load(id: string) {\n const [basePath, search] = id.split(\"?\");\n const params = new URLSearchParams(search);\n\n if (params.has(\"vite-image\")) {\n const srcSetParams = \"w=640;1024;1920&format=webp&as=srcset\";\n const metaParams = \"w=1920&format=webp&as=meta\";\n const lqipParams = \"w=20&blur=2&quality=20&format=webp&inline\";\n\n return `\n import srcSet from \"${basePath}?${srcSetParams}\";\n import meta from \"${basePath}?${metaParams}\";\n import blurDataURL from \"${basePath}?${lqipParams}\";\n \n export default {\n src: meta.src,\n width: meta.width,\n height: meta.height,\n srcSet: srcSet,\n blurDataURL: blurDataURL\n };\n `;\n }\n\n return null;\n },\n };\n\n return [viteImageMacro, imagetools(options)];\n}\n"]}
1
+ {"version":3,"sources":["../../src/plugin/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { PluginOption } from \"vite\";\nimport { imagetools } from \"vite-imagetools\";\nimport { createFilter } from \"@rollup/pluginutils\";\nimport type { ViteImageConfig, AutoApplyConfig } from \"../types\";\n\nexport type ViteImagePluginOptions = Parameters<typeof imagetools>[0];\n\n// Re-export types for convenience\nexport type { ViteImageConfig, AutoApplyConfig } from \"../types\";\n\n// Default configuration\nconst DEFAULT_BREAKPOINTS = [640, 1024, 1920];\n\n// Utility functions\nfunction getFileExtension(id: string): string | null {\n // 쿼리 파라미터 제거\n const [basePath] = id.split(\"?\");\n\n // 확장자 추출\n const match = basePath.match(/\\.([^.]+)$/);\n return match ? `.${match[1]}` : null;\n}\n\nfunction matchesExtension(id: string, extensions: string[]): boolean {\n if (!extensions || extensions.length === 0) return false;\n\n const ext = getFileExtension(id);\n if (!ext) return false;\n\n return extensions.includes(ext);\n}\n\nfunction generateSrcSetParams(breakpoints: number[]): string {\n return `w=${breakpoints.join(\";\")}&format=webp&as=srcset`;\n}\n\nfunction generateMetaParams(breakpoints: number[]): string {\n const maxWidth = Math.max(...breakpoints);\n return `w=${maxWidth}&format=webp&as=meta`;\n}\n\nfunction generateImageCode(basePath: string, breakpoints: number[]): string {\n const srcSetParams = generateSrcSetParams(breakpoints);\n const metaParams = generateMetaParams(breakpoints);\n const lqipParams = \"w=20&blur=2&quality=20&format=webp&inline\";\n\n // meta를 먼저 import하고, 그 다음에 srcSet과 blurDataURL을 import\n // 이렇게 하면 초기화 순서 문제를 방지할 수 있음\n return `\n import meta from \"${basePath}?${metaParams}\";\n import srcSet from \"${basePath}?${srcSetParams}\";\n import blurDataURL from \"${basePath}?${lqipParams}\";\n \n export default {\n src: meta.src,\n width: meta.width,\n height: meta.height,\n srcSet: srcSet,\n blurDataURL: blurDataURL\n };\n `;\n}\n\nfunction shouldAutoApply(\n id: string,\n autoApply: AutoApplyConfig | undefined,\n filter: ((id: string) => boolean) | null\n): boolean {\n // autoApply 설정이 없으면 false\n if (!autoApply) return false;\n\n // extensions가 없거나 빈 배열이면 false\n if (!autoApply.extensions || autoApply.extensions.length === 0) {\n return false;\n }\n\n // 확장자 매칭\n if (!matchesExtension(id, autoApply.extensions)) {\n return false;\n }\n\n // glob 패턴 매칭 (include/exclude)\n if (filter && !filter(id)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Vite plugin for image optimization using vite-imagetools\n * This plugin handles ?vite-image queries and uses imagetools for image processing\n *\n * @param config - Configuration options for vite-image plugin\n * @returns Array of Vite plugins (vite-image macro and imagetools)\n *\n * @example\n * ```ts\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { viteImage } from '@son426/vite-image/plugin';\n *\n * export default defineConfig({\n * plugins: [\n * ...viteImage({\n * breakpoints: [640, 1024, 1920],\n * autoApply: {\n * extensions: ['.jpg', '.png'],\n * include: ['src/**'],\n * exclude: ['src/icons/**']\n * }\n * }),\n * ],\n * });\n * ```\n */\nexport function viteImage(config?: ViteImageConfig): PluginOption[] {\n // Config 병합\n const breakpoints = config?.breakpoints ?? DEFAULT_BREAKPOINTS;\n const autoApply = config?.autoApply;\n const imagetoolsOptions = config?.imagetools;\n\n // Glob 필터 생성 (autoApply가 있을 때만)\n const filter = autoApply\n ? createFilter(autoApply.include, autoApply.exclude)\n : null;\n\n // 커스텀 플러그인: ?vite-image 쿼리를 처리\n const viteImageMacro: PluginOption = {\n name: \"vite-plugin-vite-image-macro\",\n enforce: \"pre\" as const,\n async load(id: string) {\n const [basePath, search] = id.split(\"?\");\n const params = new URLSearchParams(search);\n\n // 1. 명시적 쿼리 체크 (기존 로직)\n if (params.has(\"vite-image\")) {\n return generateImageCode(basePath, breakpoints);\n }\n\n // 2. autoApply 체크\n if (shouldAutoApply(id, autoApply, filter)) {\n // ?vite-image 쿼리를 자동으로 추가하여 처리\n return generateImageCode(basePath, breakpoints);\n }\n\n return null;\n },\n };\n\n return [viteImageMacro, imagetools(imagetoolsOptions)];\n}\n"]}
@@ -1,16 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ImgHTMLAttributes } from 'react';
3
-
4
- /**
5
- * Type definitions for vite-image
6
- */
7
- interface ResponsiveImageData {
8
- src: string;
9
- width: number;
10
- height: number;
11
- srcSet?: string;
12
- blurDataURL?: string;
13
- }
3
+ import { R as ResponsiveImageData } from '../types-B08JIQxT.js';
4
+ import 'vite-imagetools';
14
5
 
15
6
  type PlaceholderValue = "empty" | "blur" | `data:image/${string}`;
16
7
  interface BaseImageProps extends Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "srcSet" | "width" | "height"> {
@@ -37,4 +28,4 @@ loading, // loading prop (priority보다 낮은 우선순위)
37
28
  priority, // 기본값: false (Next.js Image 호환)
38
29
  className, style, onLoad, onError, ...props }: ImageProps): react_jsx_runtime.JSX.Element;
39
30
 
40
- export { type ImageProps, type ResponsiveImageData, Image as default };
31
+ export { type ImageProps, ResponsiveImageData, Image as default };
@@ -0,0 +1,25 @@
1
+ import * as vite_imagetools from 'vite-imagetools';
2
+
3
+ /**
4
+ * Type definitions for vite-image
5
+ */
6
+ interface ResponsiveImageData {
7
+ src: string;
8
+ width: number;
9
+ height: number;
10
+ srcSet?: string;
11
+ blurDataURL?: string;
12
+ }
13
+ interface AutoApplyConfig {
14
+ extensions?: string[];
15
+ include?: string[];
16
+ exclude?: string[];
17
+ }
18
+ type ViteImagePluginOptions = Parameters<typeof vite_imagetools.imagetools>[0];
19
+ interface ViteImageConfig {
20
+ breakpoints?: number[];
21
+ autoApply?: AutoApplyConfig;
22
+ imagetools?: ViteImagePluginOptions;
23
+ }
24
+
25
+ export type { AutoApplyConfig as A, ResponsiveImageData as R, ViteImageConfig as V };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@son426/vite-image",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "A Vite plugin and React component for optimized images with LQIP support using vite-imagetools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,6 +52,7 @@
52
52
  },
53
53
  "homepage": "https://github.com/son426/vite-image#readme",
54
54
  "dependencies": {
55
+ "@rollup/pluginutils": "^5.3.0",
55
56
  "vite-imagetools": "^9.0.2"
56
57
  },
57
58
  "peerDependencies": {
@@ -60,6 +61,7 @@
60
61
  "vite": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
61
62
  },
62
63
  "devDependencies": {
64
+ "@rollup/pluginutils": "^5.3.0",
63
65
  "@types/node": "^20.0.0",
64
66
  "@types/react": "^18.0.0 || ^19.0.0",
65
67
  "@types/react-dom": "^19.2.3",