vectify 2.1.0 → 2.1.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 CHANGED
@@ -116,7 +116,7 @@ src/icons/
116
116
  ### 4. Use in Your Code
117
117
 
118
118
  ```tsx
119
- import { ArrowRight, User, Settings } from './icons'
119
+ import { ArrowRight, Settings, User } from './icons'
120
120
 
121
121
  function App() {
122
122
  return (
@@ -153,6 +153,7 @@ npx vectify generate [options]
153
153
  Options:
154
154
  -c, --config Path to config file (default: vectify.config.ts)
155
155
  --dry-run Preview what will be generated without writing files
156
+ --force Force full regeneration, ignoring cache
156
157
  ```
157
158
 
158
159
  ### `vectify watch`
@@ -187,6 +188,7 @@ All available options for `defineConfig()` are documented in the tables below.
187
188
  | `suffix` | `string` | `''` | ❌ | Suffix added to all component names. | `suffix: 'Icon'` → `ArrowRightIcon` |
188
189
  | `transform` | `(name: string) => string` | - | ❌ | Custom function to transform SVG filename to component name. Overrides default PascalCase conversion and prefix/suffix. | `transform: (n) => 'X' + n` |
189
190
  | `format` | `boolean` \| `'prettier'` \| `'eslint'` \| `'biome'` \| `FormatConfig` | `false` | ❌ | Auto-format generated files after generation. See [Auto Formatting](#auto-formatting) for details. | `format: true` |
191
+ | `incremental` | `object` | `{ enabled: true }` | ❌ | Incremental generation configuration. Enables content-based caching for faster regeneration. See [Incremental Generation](#incremental-generation) for details. | `incremental: { enabled: true, cacheDir: '.vectify' }` |
190
192
 
191
193
  #### `generateOptions` Object
192
194
 
@@ -197,6 +199,45 @@ All available options for `defineConfig()` are documented in the tables below.
197
199
  | `preview` | `boolean` | `false` | Generate interactive `preview.html` for browsing all icons locally. Useful for design review. | `preview: true` |
198
200
  | `cleanOutput` | `boolean` | `false` | Remove orphaned component files that no longer have corresponding SVG files. Helps keep output directory clean. | `cleanOutput: true` |
199
201
 
202
+ #### `incremental` Object
203
+
204
+ Incremental generation uses content-based caching to dramatically speed up regeneration when only a few files change. This is especially beneficial for large icon sets (100+ icons).
205
+
206
+ | Parameter | Type | Default | Description | Example |
207
+ |-----------|------|---------|-------------|----------|
208
+ | `enabled` | `boolean` | `true` | Enable incremental generation with content-based caching. When enabled, only changed files are regenerated. | `enabled: true` |
209
+ | `cacheDir` | `string` | `'.vectify'` | Directory name for cache storage (relative to output directory). Cache is stored as `<output>/<cacheDir>/cache.json`. | `cacheDir: '.vectify'` |
210
+
211
+ **How it works:**
212
+ - Uses SHA-256 content hashing to detect real file changes (not just modification time)
213
+ - Automatically invalidates cache when configuration changes
214
+ - Provides 10-50x performance improvement for single file changes in large icon sets
215
+ - Cache is transparent and requires no manual management
216
+
217
+ **Performance:**
218
+ - First generation: Same speed as before (no cache)
219
+ - Subsequent generations with no changes: ~95% cache hit rate, 10-50x faster
220
+ - Single file change: Only regenerates changed file + index file
221
+ - Configuration change: Automatic full regeneration
222
+
223
+ **Disabling incremental generation:**
224
+ ```typescript
225
+ export default defineConfig({
226
+ framework: 'react',
227
+ input: './icons',
228
+ output: './src/icons',
229
+ incremental: {
230
+ enabled: false, // Disable caching
231
+ },
232
+ })
233
+ ```
234
+
235
+ **Force full regeneration:**
236
+ ```bash
237
+ # Bypass cache and regenerate all icons
238
+ npx vectify generate --force
239
+ ```
240
+
200
241
  #### Auto Formatting
201
242
 
202
243
  Vectify can automatically format generated files using your project's formatter. This ensures generated code matches your project's code style.
@@ -235,7 +276,7 @@ When `format: true`, Vectify looks for config files in this order:
235
276
  ```typescript
236
277
  export default defineConfig({
237
278
  format: {
238
- tool: 'prettier', // 'auto' | 'prettier' | 'eslint' | 'biome'
279
+ tool: 'prettier', // 'auto' | 'prettier' | 'eslint' | 'biome'
239
280
  args: '--single-quote', // Additional CLI arguments
240
281
  },
241
282
  })
@@ -269,6 +310,8 @@ format: false
269
310
  | `enabled` | `boolean` | `false` | Enable watch mode. Automatically regenerate components when SVG files are added, modified, or deleted in the input directory. | `enabled: true` |
270
311
  | `ignore` | `string[]` | - | Array of glob patterns to ignore during watch. | `ignore: ['**/node_modules/**', '**/.git/**']` |
271
312
  | `debounce` | `number` | `300` | Debounce delay in milliseconds before triggering regeneration. Prevents excessive rebuilds. | `debounce: 500` |
313
+ | `minFileSize` | `number` | `20` | Minimum valid SVG file size in bytes. Files smaller than this are considered empty and will be retried. | `minFileSize: 20` |
314
+ | `emptyFileRetryDelay` | `number` | `2000` | Delay in milliseconds before retrying empty SVG files. Allows time for content to be pasted. | `emptyFileRetryDelay: 2000` |
272
315
 
273
316
  #### `svgoConfig` Object
274
317
 
@@ -357,7 +400,7 @@ export default defineConfig({
357
400
  hooks: {
358
401
  beforeParse: (svg, fileName) => {
359
402
  // Replace black with currentColor for customization
360
- return svg.replace(/#000000/gi, 'currentColor')
403
+ return svg.replace(/#000000/g, 'currentColor')
361
404
  },
362
405
  afterGenerate: (code, iconName) => {
363
406
  // Add JSDoc comment to each component
@@ -393,7 +436,6 @@ The index file automatically uses the correct export style for your chosen frame
393
436
  - `keepColors: false` - Best for single-color icons that should inherit text color. Uses `currentColor` and allows runtime customization via the `color` prop.
394
437
  - `keepColors: true` - Best for multi-color brand icons. Preserves original SVG fill/stroke colors.
395
438
 
396
-
397
439
  ## Component Props
398
440
 
399
441
  All generated components accept the following props:
@@ -401,19 +443,19 @@ All generated components accept the following props:
401
443
  ```typescript
402
444
  interface IconProps {
403
445
  // Icon size (default: 24)
404
- size?: number | string
446
+ 'size'?: number | string
405
447
 
406
448
  // Icon color (default: 'currentColor')
407
- color?: string
449
+ 'color'?: string
408
450
 
409
451
  // Stroke width for stroke-based icons (default: 2)
410
- strokeWidth?: number | string
452
+ 'strokeWidth'?: number | string
411
453
 
412
454
  // CSS class name
413
- className?: string
455
+ 'className'?: string
414
456
 
415
457
  // Accessibility: icon title
416
- title?: string
458
+ 'title'?: string
417
459
 
418
460
  // Accessibility: aria-label
419
461
  'aria-label'?: string
@@ -553,10 +595,10 @@ document.getElementById('app').appendChild(icon)
553
595
 
554
596
  ```typescript
555
597
  // For single-color icons (default)
556
- keepColors: false // Uses currentColor, customizable via color prop
598
+ keepColors: false // Uses currentColor, customizable via color prop
557
599
 
558
600
  // For multi-color icons
559
- keepColors: true // Preserves original colors from SVG
601
+ keepColors: true // Preserves original colors from SVG
560
602
  ```
561
603
 
562
604
  ### 4. Project Structure
@@ -696,10 +738,10 @@ export default defineConfig({
696
738
  ```tsx
697
739
  // Before
698
740
  import { FiArrowRight } from 'react-icons/fi'
699
- <FiArrowRight size={24} />
700
741
 
701
742
  // After
702
743
  import { ArrowRight } from './icons'
744
+ <FiArrowRight size={24} />
703
745
  <ArrowRight size={24} />
704
746
  ```
705
747
 
@@ -708,10 +750,10 @@ import { ArrowRight } from './icons'
708
750
  ```tsx
709
751
  // Before
710
752
  import { Icon } from '@iconify/react'
711
- <Icon icon="mdi:arrow-right" />
712
753
 
713
754
  // After
714
755
  import { ArrowRight } from './icons'
756
+ <Icon icon="mdi:arrow-right" />
715
757
  <ArrowRight />
716
758
  ```
717
759
 
package/README.zh-CN.md CHANGED
@@ -116,7 +116,7 @@ src/icons/
116
116
  ### 4. 在代码中使用
117
117
 
118
118
  ```tsx
119
- import { ArrowRight, User, Settings } from './icons'
119
+ import { ArrowRight, Settings, User } from './icons'
120
120
 
121
121
  function App() {
122
122
  return (
@@ -153,6 +153,7 @@ npx vectify generate [选项]
153
153
  选项:
154
154
  -c, --config 配置文件路径 (默认: vectify.config.ts)
155
155
  --dry-run 预览将要生成的内容而不实际写入文件
156
+ --force 强制完全重新生成,忽略缓存
156
157
  ```
157
158
 
158
159
  ### `vectify watch`
@@ -187,6 +188,7 @@ npx vectify watch [选项]
187
188
  | `suffix` | `string` | `''` | ❌ | 添加到所有组件名称后的后缀 | `suffix: 'Icon'` → `ArrowRightIcon` |
188
189
  | `transform` | `(name: string) => string` | - | ❌ | 自定义函数,将 SVG 文件名转换为组件名。覆盖默认的 PascalCase 转换和 prefix/suffix | `transform: (n) => 'X' + n` |
189
190
  | `format` | `boolean` \| `'prettier'` \| `'eslint'` \| `'biome'` \| `FormatConfig` | `false` | ❌ | 生成后自动格式化文件。详见 [自动格式化](#自动格式化) | `format: true` |
191
+ | `incremental` | `object` | `{ enabled: true }` | ❌ | 增量生成配置。启用基于内容的缓存以加快重新生成速度。详见 [增量生成](#增量生成) | `incremental: { enabled: true, cacheDir: '.vectify' }` |
190
192
 
191
193
  #### `generateOptions` 对象
192
194
 
@@ -197,6 +199,45 @@ npx vectify watch [选项]
197
199
  | `preview` | `boolean` | `false` | 生成交互式 `preview.html` 用于本地浏览所有图标。适合设计审查 | `preview: true` |
198
200
  | `cleanOutput` | `boolean` | `false` | 移除不再有对应 SVG 文件的孤立组件。帮助保持输出目录整洁 | `cleanOutput: true` |
199
201
 
202
+ #### `incremental` 对象
203
+
204
+ 增量生成使用基于内容的缓存来显著加快重新生成速度,特别适合大型图标集(100+ 图标)。
205
+
206
+ | 参数 | 类型 | 默认值 | 说明 | 示例 |
207
+ |------|------|--------|------|------|
208
+ | `enabled` | `boolean` | `true` | 启用基于内容缓存的增量生成。启用后,只会重新生成变化的文件 | `enabled: true` |
209
+ | `cacheDir` | `string` | `'.vectify'` | 缓存存储目录名(相对于输出目录)。缓存存储为 `<output>/<cacheDir>/cache.json` | `cacheDir: '.vectify'` |
210
+
211
+ **工作原理:**
212
+ - 使用 SHA-256 内容哈希检测真实文件变化(而非仅修改时间)
213
+ - 配置变更时自动失效缓存
214
+ - 对于大型图标集的单文件变更,提供 10-50 倍性能提升
215
+ - 缓存是透明的,无需手动管理
216
+
217
+ **性能表现:**
218
+ - 首次生成:与之前速度相同(无缓存)
219
+ - 无变更的后续生成:约 95% 缓存命中率,快 10-50 倍
220
+ - 单文件变更:仅重新生成变化的文件 + 索引文件
221
+ - 配置变更:自动完全重新生成
222
+
223
+ **禁用增量生成:**
224
+ ```typescript
225
+ export default defineConfig({
226
+ framework: 'react',
227
+ input: './icons',
228
+ output: './src/icons',
229
+ incremental: {
230
+ enabled: false, // 禁用缓存
231
+ },
232
+ })
233
+ ```
234
+
235
+ **强制完全重新生成:**
236
+ ```bash
237
+ # 绕过缓存并重新生成所有图标
238
+ npx vectify generate --force
239
+ ```
240
+
200
241
  #### 自动格式化
201
242
 
202
243
  Vectify 可以使用项目中的格式化工具自动格式化生成的文件。确保生成的代码符合项目的代码风格。
@@ -235,7 +276,7 @@ export default defineConfig({
235
276
  ```typescript
236
277
  export default defineConfig({
237
278
  format: {
238
- tool: 'prettier', // 'auto' | 'prettier' | 'eslint' | 'biome'
279
+ tool: 'prettier', // 'auto' | 'prettier' | 'eslint' | 'biome'
239
280
  args: '--single-quote', // 额外的 CLI 参数
240
281
  },
241
282
  })
@@ -269,6 +310,8 @@ format: false
269
310
  | `enabled` | `boolean` | `false` | 启用监听模式。在输入目录中添加、修改或删除 SVG 文件时自动重新生成组件 | `enabled: true` |
270
311
  | `ignore` | `string[]` | - | 监听时忽略的 glob 模式数组 | `ignore: ['**/node_modules/**', '**/.git/**']` |
271
312
  | `debounce` | `number` | `300` | 触发重新生成前的防抖延迟(毫秒)。防止过度重新构建 | `debounce: 500` |
313
+ | `minFileSize` | `number` | `20` | 最小有效 SVG 文件大小(字节)。小于此大小的文件被视为空文件并将重试 | `minFileSize: 20` |
314
+ | `emptyFileRetryDelay` | `number` | `2000` | 重试空 SVG 文件前的延迟(毫秒)。允许时间粘贴内容 | `emptyFileRetryDelay: 2000` |
272
315
 
273
316
  #### `svgoConfig` 对象
274
317
 
@@ -357,7 +400,7 @@ export default defineConfig({
357
400
  hooks: {
358
401
  beforeParse: (svg, fileName) => {
359
402
  // 将黑色替换为 currentColor 以便自定义
360
- return svg.replace(/#000000/gi, 'currentColor')
403
+ return svg.replace(/#000000/g, 'currentColor')
361
404
  },
362
405
  afterGenerate: (code, iconName) => {
363
406
  // 为每个组件添加 JSDoc 注释
@@ -393,7 +436,6 @@ export default defineConfig({
393
436
  - `keepColors: false` - 适合应继承文本颜色的单色图标。使用 `currentColor` 并允许通过 `color` 属性进行运行时自定义。
394
437
  - `keepColors: true` - 适合多色品牌图标。保留原始 SVG 的 fill/stroke 颜色。
395
438
 
396
-
397
439
  ## 🎨 组件属性
398
440
 
399
441
  所有生成的组件都接受以下属性:
@@ -401,19 +443,19 @@ export default defineConfig({
401
443
  ```typescript
402
444
  interface IconProps {
403
445
  // 图标大小 (默认: 24)
404
- size?: number | string
446
+ 'size'?: number | string
405
447
 
406
448
  // 图标颜色 (默认: 'currentColor')
407
- color?: string
449
+ 'color'?: string
408
450
 
409
451
  // 描边图标的描边宽度 (默认: 2)
410
- strokeWidth?: number | string
452
+ 'strokeWidth'?: number | string
411
453
 
412
454
  // CSS 类名
413
- className?: string
455
+ 'className'?: string
414
456
 
415
457
  // 无障碍:图标标题
416
- title?: string
458
+ 'title'?: string
417
459
 
418
460
  // 无障碍:aria-label
419
461
  'aria-label'?: string
@@ -553,10 +595,10 @@ document.getElementById('app').appendChild(icon)
553
595
 
554
596
  ```typescript
555
597
  // 单色图标(默认)
556
- keepColors: false // 使用 currentColor,可通过 color 属性自定义
598
+ keepColors: false // 使用 currentColor,可通过 color 属性自定义
557
599
 
558
600
  // 多色图标
559
- keepColors: true // 保留 SVG 中的原始颜色
601
+ keepColors: true // 保留 SVG 中的原始颜色
560
602
  ```
561
603
 
562
604
  ### 4. 项目结构
@@ -696,10 +738,10 @@ export default defineConfig({
696
738
  ```tsx
697
739
  // 之前
698
740
  import { FiArrowRight } from 'react-icons/fi'
699
- <FiArrowRight size={24} />
700
741
 
701
742
  // 之后
702
743
  import { ArrowRight } from './icons'
744
+ <FiArrowRight size={24} />
703
745
  <ArrowRight size={24} />
704
746
  ```
705
747
 
@@ -708,10 +750,10 @@ import { ArrowRight } from './icons'
708
750
  ```tsx
709
751
  // 之前
710
752
  import { Icon } from '@iconify/react'
711
- <Icon icon="mdi:arrow-right" />
712
753
 
713
754
  // 之后
714
755
  import { ArrowRight } from './icons'
756
+ <Icon icon="mdi:arrow-right" />
715
757
  <ArrowRight />
716
758
  ```
717
759