@son426/vite-image 0.1.9 → 0.2.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 CHANGED
@@ -23,3 +23,5 @@ SOFTWARE.
23
23
 
24
24
 
25
25
 
26
+
27
+
package/README.md CHANGED
@@ -21,13 +21,51 @@ Simply add the plugin to your config, and start using the `<Image />` component
21
21
 
22
22
  Add it to `vite.config.ts`, and use it like this:
23
23
 
24
+ **Option 1: Using query string (default)**
25
+
24
26
  ```tsx
25
27
  // vite.config.ts
26
- viteImage({
27
- autoApply: {
28
- extensions: [".jpg", ".png", ".webp"],
29
- include: ["src/assets/**"],
30
- },
28
+ import { defineConfig } from "vite";
29
+ import { viteImage } from "@son426/vite-image/plugin";
30
+
31
+ export default defineConfig({
32
+ plugins: [
33
+ viteImage(), // Default breakpoints: [640, 1024, 1920]
34
+ ],
35
+ });
36
+
37
+ // Component
38
+ import Image from "@son426/vite-image/react";
39
+ import myBg from "./assets/background.jpg?vite-image";
40
+
41
+ export default function Page() {
42
+ return (
43
+ <Image
44
+ src={myBg}
45
+ alt="Optimized Background"
46
+ fill
47
+ priority
48
+ placeholder="blur"
49
+ />
50
+ );
51
+ }
52
+ ```
53
+
54
+ **Option 2: Auto-apply without query string**
55
+
56
+ ```tsx
57
+ // vite.config.ts
58
+ import { defineConfig } from "vite";
59
+ import { viteImage } from "@son426/vite-image/plugin";
60
+
61
+ export default defineConfig({
62
+ plugins: [
63
+ viteImage({
64
+ autoApply: {
65
+ extensions: [".jpg"],
66
+ },
67
+ }),
68
+ ],
31
69
  });
32
70
 
33
71
  // Component
@@ -47,6 +85,8 @@ export default function Page() {
47
85
  }
48
86
  ```
49
87
 
88
+ > **Note**: For auto-apply, you'll need to add type declarations. See the [TypeScript Setup](#typescript-setup) section below.
89
+
50
90
  ## Installation
51
91
 
52
92
  Install the package. `vite-imagetools` and `@rollup/pluginutils` are included as dependencies.
@@ -69,28 +109,14 @@ Just a standard Vite + React project.
69
109
 
70
110
  ## TypeScript Setup
71
111
 
72
- **⚠️ Temporary Setup Required**: Currently, you need to add type declarations manually. This will be automated in a future update.
73
-
74
- Add the following to your project's type definition file (e.g., `src/vite-env.d.ts`):
112
+ If you are using TypeScript, add the following to your project's type definition file (e.g., `src/vite-env.d.ts`):
75
113
 
76
114
  ```typescript
77
115
  /// <reference types="vite/client" />
78
-
79
- interface ResponsiveImageData {
80
- src: string;
81
- width: number;
82
- height: number;
83
- srcSet?: string;
84
- blurDataURL?: string;
85
- }
86
-
87
- declare module "*?vite-image" {
88
- const content: ResponsiveImageData;
89
- export default content;
90
- }
116
+ /// <reference types="@son426/vite-image/client" />
91
117
  ```
92
118
 
93
- This ensures TypeScript recognizes `?vite-image` imports. Sorry for the temporary manual step—we're working on automating this.
119
+ This ensures TypeScript recognizes `?vite-image` imports.
94
120
 
95
121
  ## Usage
96
122
 
@@ -186,7 +212,14 @@ viteImage({
186
212
 
187
213
  // Add type declarations for autoApply extensions
188
214
  // In your project's vite-env.d.ts or a custom .d.ts file:
189
- // (Make sure you've already added the ResponsiveImageData interface from the TypeScript Setup section above)
215
+
216
+ interface ResponsiveImageData {
217
+ src: string;
218
+ width: number;
219
+ height: number;
220
+ srcSet?: string;
221
+ blurDataURL?: string;
222
+ }
190
223
 
191
224
  declare module "*.jpg" {
192
225
  const imageData: ResponsiveImageData;
@@ -338,7 +371,7 @@ import Image from "@son426/vite-image/react";
338
371
  import type { ImageProps } from "@son426/vite-image/react";
339
372
  ```
340
373
 
341
- **Note**: After setting up the type declarations in the "TypeScript Setup" section above, you can use `ResponsiveImageData` directly in your code without importing it.
374
+ **Note**: When using `autoApply` with custom extensions, you need to define the `ResponsiveImageData` interface in your type definition file (as shown in the "Without query string" section above) since `.d.ts` files cannot use imports.
342
375
 
343
376
  ## How It Works
344
377
 
@@ -1,3 +1,4 @@
1
+ // client.d.ts
1
2
  /// <reference types="vite/client" />
2
3
 
3
4
  /**
@@ -5,7 +6,13 @@
5
6
  * These types extend the default vite-imagetools types
6
7
  */
7
8
 
8
- import type { ResponsiveImageData } from "./types";
9
+ interface ResponsiveImageData {
10
+ src: string;
11
+ width: number;
12
+ height: number;
13
+ srcSet?: string;
14
+ blurDataURL?: string; // Base64 encoded blur placeholder (Next.js Image compatible)
15
+ }
9
16
 
10
17
  // vite-image 쿼리 파라미터 타입
11
18
  declare module "*?vite-image" {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
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
+ {"version":3,"sources":["../src/plugin/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// src/plugin/index.ts\n\nimport 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 +1 @@
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
+ {"version":3,"sources":["../../src/plugin/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// src/plugin/index.ts\n\nimport 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@son426/vite-image",
3
- "version": "0.1.9",
3
+ "version": "0.2.1",
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",
@@ -18,11 +18,14 @@
18
18
  "./plugin": {
19
19
  "types": "./dist/plugin/index.d.ts",
20
20
  "import": "./dist/plugin/index.js"
21
+ },
22
+ "./client": {
23
+ "types": "./client.d.ts"
21
24
  }
22
25
  },
23
26
  "files": [
24
27
  "dist",
25
- "types.d.ts",
28
+ "client.d.ts",
26
29
  "README.md",
27
30
  "LICENSE"
28
31
  ],