docs: обновить документацию generated-контракта

- описаны единая конфигурация и exact modes
- обновлена структура .svg-sprite
- удалены материалы legacy pipeline
- синхронизированы русская и английская версии skill
This commit is contained in:
2026-07-13 20:07:42 +03:00
parent f4f464a568
commit 7992adc9d3
55 changed files with 618 additions and 2168 deletions

View File

@@ -1,102 +0,0 @@
# Legacy mode
[← Главная](../../README_RU.md)
Краткая инструкция по генерации централизованных SVG-спрайтов форматов `symbol` и `stack` с optional HTML preview.
## 1. Установите пакет
```bash
npm install --save-dev @gromlab/svg-sprites
```
## 2. Подготовьте иконки и конфиг
```text
project/
├── src/assets/icons/
│ ├── check.svg
│ └── folder.svg
└── svg-sprites.config.ts
```
```ts
// svg-sprites.config.ts
import { defineLegacyConfig } from '@gromlab/svg-sprites'
export default defineLegacyConfig({
output: 'public/sprites',
preview: true,
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'symbol',
},
],
})
```
## 3. Добавьте генерацию
```json
{
"scripts": {
"sprites": "svg-sprites --mode legacy .",
"prebuild": "npm run sprites"
}
}
```
Запустите локально установленный пакет через script:
```bash
npm run sprites
```
Результат:
```text
public/sprites/
├── icons.sprite.svg
└── preview.html
```
При `preview: false` HTML-файл не создаётся. Для формата `stack` укажите `format: 'stack'`.
## 4. Используйте symbol-спрайт
```html
<svg width="24" height="24" aria-label="Готово">
<use href="/sprites/icons.sprite.svg#check"></use>
</svg>
```
## Несколько спрайтов
Добавьте несколько записей в `sprites`:
```ts
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'symbol',
},
{
name: 'logos',
input: 'src/assets/logos',
format: 'stack',
},
]
```
Все результаты и общий `preview.html` будут записаны в `output`.
## Если что-то не работает
- Не найден конфиг: убедитесь, что `svg-sprites.config.ts` находится в переданном корне.
- Нет иконок: проверьте `sprites[].input` и расширение `.svg`.
- Не нужен preview: установите `preview: false`.
Для программного запуска используйте [`generateLegacy`](programmatic-api.md#generatelegacy).

View File

@@ -1,122 +0,0 @@
# Миграция с 0.1.x на 1.0
[← Главная](../../README_RU.md)
Версия 1.0 разделяет локальную генерацию для React и Next.js и централизованный legacy-режим. Старый config нельзя смешивать с новым API в одном вызове CLI.
## Установка
Установите пакет как development dependency, чтобы миграция использовала версию из lockfile проекта:
```bash
npm install --save-dev @gromlab/svg-sprites
```
## CLI
CLI теперь всегда требует явный `--mode` и путь к каталогу конфигурации:
```text
"sprites": "svg-sprites"
→ "sprites": "svg-sprites --mode <mode> <path>"
```
Выберите mode по окружению:
| Окружение | Mode |
|---|---|
| React + Vite | `react@vite` |
| React + Webpack 5 | `react@webpack` |
| Next.js App Router + Turbopack | `next@app/turbopack` |
| Next.js App Router + Webpack 5 | `next@app/webpack` |
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
| Централизованная старая схема | `legacy` |
## React и Next.js
Вместо корневого `svg-sprites.config.ts` создайте локальный `svg-sprite.config.ts` рядом с набором иконок:
```ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
name: 'global',
inputFolder: './icons',
})
```
Для обычного React используйте `defineReactSpriteConfig`. Папку и явный список общих SVG можно объединить через `inputFolder` и `inputFiles`.
Добавьте локальный CLI с выбранным mode в `package.json`, например:
```json
{
"scripts": {
"sprite:global": "svg-sprites --mode next@app/turbopack src/ui/global/svg-sprite"
}
}
```
Запустите его командой `npm run sprite:global` до импорта generated-компонента.
Старые `publicPath` и `react` больше не нужны. Generated-модуль создаётся рядом с конфигом, сам добавляет `.gitignore`, а Vite, Webpack или Next.js выпускает SVG как отдельный asset с content hash.
Компонент `<SvgSprite icon="..." />` заменяется компонентом, имя которого выводится из `name`:
```tsx
<GlobalIcon icon="check" />
```
Для просмотра иконок добавьте `<SpriteViewer>` как debug-страницу приложения. Отдельный `preview.html` остаётся только в legacy-режиме.
## Legacy-режим
Если централизованную структуру нужно сохранить, переименуйте helper и поля формата:
```ts
import { defineLegacyConfig } from '@gromlab/svg-sprites'
export default defineLegacyConfig({
output: 'public/sprites',
preview: true,
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'stack',
},
],
})
```
- `defineConfig` заменён на `defineLegacyConfig`;
- `sprites[].mode` переименован в `sprites[].format`;
- `generate` заменён на `generateLegacy`;
- `loadConfig` заменён на `loadLegacyConfig`;
- `publicPath` и генерация старого общего React-компонента удалены.
Добавьте локальный CLI в `package.json`:
```json
{
"scripts": {
"sprites": "svg-sprites --mode legacy ."
}
}
```
Запустите его командой `npm run sprites`.
## Программный API
Пакет распространяется только как ESM. Замените `require()` на `import`.
`compileSpriteContent` теперь возвращает `Promise<Uint8Array>`, чтобы публичные декларации не требовали установки `@types/node`. В Node.js фактический результат совместим с API, принимающими `Uint8Array`.
## После миграции
1. Добавьте явную команду генерации перед `dev`, `build` и `typecheck`.
2. Создайте новый output и запустите проверку типов, пока старые artifacts остаются доступны.
3. Замените imports и проверьте иконки и цветовые переменные через `SpriteViewer` или legacy `preview.html`.
4. Только после этого удалите подтверждённые старые generated-файлы и устаревшие ignore rules, не затрагивая исходные SVG.

View File

@@ -22,19 +22,28 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@app/turbopack',
name: 'file-manager',
description: 'Иконки файлового менеджера',
})
```
Корневой barrel принадлежит приложению:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
## 3. Добавьте генерацию
Для Turbopack:
@@ -42,7 +51,7 @@ export default defineNextSpriteConfig({
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode next@app/turbopack src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager"
}
@@ -85,7 +94,7 @@ Viewer интерактивен, поэтому для него нужна от
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('@/ui/file-manager/svg-sprite/manifest'),
() => import('@/ui/file-manager/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
]
export default function SpritesPage() {

View File

@@ -22,25 +22,34 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@pages/webpack',
name: 'file-manager',
description: 'Иконки файлового менеджера',
})
```
Корневой barrel принадлежит приложению:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
## 3. Добавьте генерацию
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode next@pages/webpack src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager"
}
@@ -77,7 +86,7 @@ export function getServerSideProps() {
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('@/ui/file-manager/svg-sprite/manifest'),
() => import('@/ui/file-manager/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
]
export default function SpritesPage() {

View File

@@ -2,100 +2,65 @@
[← Главная](../../README_RU.md)
Пакет предоставляет основную Node.js точку входа и отдельный React runtime entry. Обе точки распространяются только как ESM и подключаются через `import`.
Пакет распространяется как ESM и предоставляет единый Node.js API генерации. React runtime с `SpriteViewer` находится в отдельной точке входа `@gromlab/svg-sprites/react`.
Для разрешения `@gromlab/svg-sprites/react` в TypeScript используйте `moduleResolution: "bundler"`, `"node16"` или `"nodenext"`.
## Основной entry
## `generateSprite`
```ts
import {
defineNextSpriteConfig,
defineReactSpriteConfig,
generateNextSprite,
generateReactSprite,
} from '@gromlab/svg-sprites'
```
import { generateSprite } from '@gromlab/svg-sprites'
Основной entry не импортирует React и может использоваться в CLI, build scripts и Node.js инструментах.
## `generateReactSprite`
```ts
import { generateReactSprite } from '@gromlab/svg-sprites'
const result = await generateReactSprite(
'src/ui/file-manager/svg-sprite',
'vite',
const result = await generateSprite(
'src/ui/file-manager/svg-sprite/svg-sprite.config.ts',
)
```
Второй аргумент обязателен:
Первый аргумент принимает полный путь к config-файлу с любым именем и расширением `.ts`, `.js` или `.json`. Каталог вместо файла включает config-less режим: корнем sprite-модуля становится этот каталог.
Второй аргумент содержит необязательные overrides и всегда имеет приоритет над конфигом:
```ts
type ReactAssetTarget = 'vite' | 'webpack'
```
Результат:
```ts
type ReactSpriteGenerationResult = {
name: string
rootDir: string
generatedDir: string
spritePath: string
manifestPath: string
iconCount: number
target: 'vite' | 'webpack'
}
```
```ts
console.log(result.name)
console.log(result.iconCount)
console.log(result.spritePath)
console.log(result.manifestPath)
```
Функция загружает `svg-sprite.config.ts` из указанного корня, компилирует SVG и безопасно обновляет managed-файлы.
## `generateNextSprite`
```ts
import { generateNextSprite } from '@gromlab/svg-sprites'
const result = await generateNextSprite(
'src/ui/file-manager/svg-sprite',
{
router: 'app',
bundler: 'turbopack',
await generateSprite('src/ui/file-manager/svg-sprite/custom-config.json', {
mode: 'react@webpack',
name: 'documents',
inputFolder: './assets',
inputFiles: ['../../shared/search.svg'],
transform: {
addTransition: false,
},
)
generatedNotice: false,
})
```
Доступные значения:
Порядок разрешения настроек:
```ts
type NextSpriteGenerationOptions = {
router: 'app' | 'pages'
bundler: 'turbopack' | 'webpack'
}
```text
defaults → config → API overrides
```
Результат дополнительно содержит выбранные `router`, `bundler` и полный target вида `next@app/turbopack`.
## `defineReactSpriteConfig`
Для полностью программной генерации передайте каталог и все обязательные настройки через overrides:
```ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
await generateSprite('src/ui/file-manager/svg-sprite', {
mode: 'react@vite',
name: 'file-manager',
inputFiles: [
'../../shared/search.svg',
'../../shared/settings.svg',
],
})
```
export default defineReactSpriteConfig({
## Конфигурация
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'react@vite',
name: 'file-manager',
description: 'Иконки файлового менеджера',
inputFolder: './icons',
inputFiles: [
'../../shared/icons/check.svg',
],
inputFiles: ['../../shared/check.svg'],
transform: {
removeSize: true,
replaceColors: true,
@@ -105,99 +70,54 @@ export default defineReactSpriteConfig({
})
```
`inputFolder` и `inputFiles` объединяются. Хелпер возвращает конфиг без runtime-преобразований и предоставляет TypeScript autocomplete.
`defineSpriteConfig` является identity helper для TypeScript autocomplete. JS может экспортировать тот же объект через `export default`, а JSON содержит объект непосредственно.
## `defineNextSpriteConfig`
## Специализированные обёртки
Специализированные функции доступны как обёртки над `generateSprite`:
```ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { generateNextSprite, generateReactSprite } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
name: 'file-manager',
description: 'Иконки файлового менеджера',
inputFolder: './icons',
await generateReactSprite('path/to/config.ts', 'vite')
await generateNextSprite('path/to/config.ts', {
router: 'app',
bundler: 'turbopack',
})
```
Next.js использует тот же контракт конфигурации, что и React presets.
Явно переданный target перекрывает `mode` из файла. Для нового кода используйте `generateSprite`.
## `generateLegacy`
## Config API
```ts
import { generateLegacy } from '@gromlab/svg-sprites'
const results = await generateLegacy({
output: 'public/sprites',
preview: false,
sprites: [
{
name: 'icons',
input: 'src/assets/icons',
format: 'symbol',
},
],
})
import {
loadSpriteConfig,
resolveSpriteConfig,
validateSpriteConfig,
} from '@gromlab/svg-sprites'
```
Возвращается массив:
- `loadSpriteConfig(file)` загружает явно указанный `.ts`, `.js` или `.json` файл.
- `validateSpriteConfig(value)` выполняет runtime-валидацию объекта.
- `resolveSpriteConfig(root, config, overrides)` объединяет значения, добавляет defaults и разрешает пути относительно `root`.
```ts
type SpriteResult = {
name: string
format: 'symbol' | 'stack'
spritePath: string
iconCount: number
}
```
Подробнее: [Legacy mode](legacy.md).
## Низкоуровневые функции
Основная точка входа также экспортирует:
## Низкоуровневый compiler
```ts
import {
compileSprite,
compileSpriteContent,
createShapeTransform,
generatePreview,
loadLegacyConfig,
loadReactSpriteConfig,
resolveSpriteEntry,
resolveSprites,
} from '@gromlab/svg-sprites'
```
Эти функции предназначены для собственного orchestration поверх существующего compiler и writer. Для стандартного использования предпочтительны `generateReactSprite` и `generateLegacy`.
Эти функции предназначены для собственного orchestration. Стандартная генерация должна выполняться через `generateSprite`.
## React runtime entry
## React runtime
```tsx
import { SpriteViewer } from '@gromlab/svg-sprites/react'
```
Типы:
```ts
import type {
SpriteManifest,
SpriteManifestColor,
SpriteManifestIcon,
SpriteManifestLoader,
SpriteManifestModule,
SpriteViewerColorTheme,
SpriteViewerProps,
SpriteViewerSource,
SpriteViewerSources,
} from '@gromlab/svg-sprites/react'
```
React entry содержит `'use client'` и предназначен для debug-инструментов. Generated production-компоненты импортируются из локальных sprite-модулей приложения, а не из React entry пакета.
`SpriteViewerProps.colorTheme` принимает `auto | light | dark`. Значение `auto` используется по умолчанию и следует `prefers-color-scheme`; для синхронизации с темой приложения передавайте вычисленное `light` или `dark`.
## Связанные руководства
- [React + Vite](react-vite.md)
- [React + Webpack 5](react-webpack.md)
`SpriteViewer` принимает generated manifests, lazy loaders или результат `import.meta.glob`. Эта точка входа содержит `'use client'` и предназначена для debug-инструментов; production-компоненты импортируются из локальных sprite-модулей приложения.

View File

@@ -19,6 +19,7 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
@@ -28,24 +29,32 @@ src/ui/file-manager/svg-sprite/
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineReactSpriteConfig({
export default defineSpriteConfig({
mode: 'react@vite',
name: 'file-manager',
description: 'Иконки файлового менеджера',
})
```
Корневой barrel принадлежит приложению и явно возвращает generated API:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
По умолчанию SVG берутся из `./icons`. Общие иконки из других папок можно добавить через `inputFiles`: папка и список объединяются в один спрайт.
Полный список опций находится в разделе [«Конфигурация React и Next.js»](reference.md#конфигурация-react-и-nextjs).
Полный список опций находится в разделе [«Единая конфигурация»](reference.md#единая-конфигурация).
## 4. Добавьте генерацию в package.json
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode react@vite src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager",
"pretypecheck": "npm run sprite:file-manager"
@@ -96,7 +105,7 @@ import { SpriteViewer } from '@gromlab/svg-sprites/react'
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
const sources = import.meta.glob<SpriteManifestModule>(
'/src/**/svg-sprite/manifest.ts',
'/src/**/svg-sprite/.svg-sprite/svg-sprite.manifest.js',
)
export const IconsDebugPage = () => (
@@ -104,13 +113,13 @@ export const IconsDebugPage = () => (
)
```
Vite автоматически найдёт generated `manifest.ts` каждого React-спрайта. Шаблон `import.meta.glob` должен быть строковым литералом, а генерация должна выполниться до запуска Vite.
Vite автоматически найдёт generated manifest каждого React-спрайта. Шаблон `import.meta.glob` должен быть строковым литералом, а генерация должна выполниться до запуска Vite.
Размещайте Viewer только на debug-маршруте или во внутреннем инструменте.
## Если что-то не работает
- Нет `index.ts`: запустите `npm run sprite:file-manager`.
- Viewer не видит спрайт: проверьте путь glob и наличие `manifest.ts`.
- Нет `.svg-sprite/index.js`: запустите `npm run sprite:file-manager`.
- Viewer не видит спрайт: проверьте glob-путь к `.svg-sprite/svg-sprite.manifest.js`.
- Ошибка `Refusing to overwrite a user file`: в generated-пути находится пользовательский файл.
- Иконка не меняет цвет: используйте `color` или `--icon-color-N`.

View File

@@ -19,6 +19,7 @@ src/ui/file-manager/svg-sprite/
├── icons/
│ ├── check.svg
│ └── folder.svg
├── index.ts
└── svg-sprite.config.ts
```
@@ -28,24 +29,32 @@ src/ui/file-manager/svg-sprite/
```ts
// src/ui/file-manager/svg-sprite/svg-sprite.config.ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineReactSpriteConfig({
export default defineSpriteConfig({
mode: 'react@webpack',
name: 'file-manager',
description: 'Иконки файлового менеджера',
})
```
Корневой barrel принадлежит приложению и явно возвращает generated API:
```ts
// src/ui/file-manager/svg-sprite/index.ts
export * from './.svg-sprite'
```
По умолчанию SVG берутся из `./icons`. Общие иконки из других папок можно добавить через `inputFiles`: папка и список объединяются в один спрайт.
Полный список опций находится в разделе [«Конфигурация React и Next.js»](reference.md#конфигурация-react-и-nextjs).
Полный список опций находится в разделе [«Единая конфигурация»](reference.md#единая-конфигурация).
## 4. Добавьте генерацию в package.json
```json
{
"scripts": {
"sprite:file-manager": "svg-sprites --mode react@webpack src/ui/file-manager/svg-sprite",
"sprite:file-manager": "svg-sprites src/ui/file-manager/svg-sprite/svg-sprite.config.ts",
"predev": "npm run sprite:file-manager",
"prebuild": "npm run sprite:file-manager",
"pretypecheck": "npm run sprite:file-manager"
@@ -87,7 +96,7 @@ Webpack обработает generated `new URL('./sprite.svg', import.meta.url)
Если проект уже использует собственный SVG loader, убедитесь, что он не перехватывает generated `sprite.svg` вместо Asset Modules.
Generated-компонент импортирует `styles.module.css`, поэтому Webpack должен обрабатывать CSS Modules через `css-loader` и `style-loader` либо `MiniCssExtractPlugin`. Если TypeScript-проект не содержит декларации для CSS Modules, добавьте её отдельно.
Generated-компонент импортирует `react/react-component.module.css`, поэтому Webpack должен обрабатывать CSS Modules через `css-loader` и `style-loader` либо `MiniCssExtractPlugin`. Если TypeScript-проект не содержит декларации для CSS Modules, добавьте её отдельно.
## 6. Добавьте debug-страницу
@@ -97,8 +106,8 @@ Webpack не поддерживает Vite API `import.meta.glob`, поэтом
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('./ui/file-manager/svg-sprite/manifest'),
() => import('./ui/navigation/svg-sprite/manifest'),
() => import('./ui/file-manager/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('./ui/navigation/svg-sprite/.svg-sprite/svg-sprite.manifest.js'),
]
export const IconsDebugPage = () => (
@@ -112,8 +121,8 @@ export const IconsDebugPage = () => (
## Если что-то не работает
- Нет `index.ts`: запустите `npm run sprite:file-manager`.
- Viewer не загружает спрайт: проверьте путь в `import()` и наличие `manifest.ts`.
- Нет `.svg-sprite/index.js`: запустите `npm run sprite:file-manager`.
- Viewer не загружает спрайт: проверьте путь в `import()` к `.svg-sprite/svg-sprite.manifest.js`.
- Неверный URL asset: проверьте `output.publicPath`.
- SVG перехватывает другой loader: исключите generated sprite из несовместимого правила.

View File

@@ -8,7 +8,6 @@
- [Next.js Pages Router](next-pages.md)
- [React + Vite](react-vite.md)
- [React + Webpack 5](react-webpack.md)
- [Нативный HTML и классические SVG-спрайты](legacy.md)
## Требования
@@ -25,10 +24,10 @@ npm install --save-dev @gromlab/svg-sprites
## CLI и режимы генерации
CLI принимает один режим и путь к каталогу конфигурации:
CLI принимает ровно один путь: явно выбранный config-файл либо каталог для config-less генерации:
```text
svg-sprites --mode <mode> <path>
svg-sprites [options] <config-file-or-directory>
```
| Среда | Mode |
@@ -39,20 +38,24 @@ svg-sprites --mode <mode> <path>
| Next.js App Router + Webpack 5 | `next@app/webpack` |
| Next.js Pages Router + Turbopack | `next@pages/turbopack` |
| Next.js Pages Router + Webpack 5 | `next@pages/webpack` |
| Классические `stack`- и `symbol`-спрайты | `legacy` |
Современные React- и Next.js-режимы используют локальный `svg-sprite.config.ts`. Legacy-режим использует отдельный `svg-sprites.config.ts` и описан в [собственном руководстве](legacy.md).
Config-файл может иметь любое имя и расширение `.ts`, `.js` или `.json`. CLI не ищет конфиг по соглашению: файл нужно передать явно. В руководствах используется рекомендуемое имя `svg-sprite.config.ts`.
Если передан каталог, все настройки берутся из CLI. Если передан config-файл, CLI-параметры перекрывают значения файла. Общий порядок: `defaults → config → CLI`.
Доступны `--mode`, `--name`, `--description`, `--input-folder`, повторяемый `--input-file`, а также пары `--remove-size`/`--no-remove-size`, `--replace-colors`/`--no-replace-colors`, `--add-transition`/`--no-add-transition` и `--generated-notice`/`--no-generated-notice`. Переданные transform-флаги перекрывают отдельные поля, а хотя бы один `--input-file` заменяет весь массив `inputFiles` из config.
Mode должен соответствовать сборщику приложения. Генератор создаёт разный способ подключения SVG asset для Vite и сборщиков, совместимых с Webpack Asset Modules.
## Конфигурация React и Next.js
## Единая конфигурация
Каждый каталог с `svg-sprite.config.ts` описывает один независимый спрайт.
Каждый config-файл описывает один независимый спрайт.
```ts
import { defineNextSpriteConfig } from '@gromlab/svg-sprites'
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@app/turbopack',
name: 'app',
description: 'Общие иконки приложения',
inputFolder: './local-icons',
@@ -69,18 +72,13 @@ export default defineNextSpriteConfig({
})
```
Для React используйте `defineReactSpriteConfig`. Контракт конфигурации одинаковый:
```ts
import { defineReactSpriteConfig } from '@gromlab/svg-sprites'
```
| Опция | Тип | По умолчанию | Назначение |
|---|---|---|---|
| `mode` | `SpriteMode` | Нет | Режим генерации; можно передать через CLI/API |
| `name` | `string` | Выводится из каталога | Имя спрайта, компонента и публичных типов |
| `description` | `string` | Нет | Описание для типов и debug manifest |
| `inputFolder` | `string` | `./icons` | Каталог с SVG относительно конфига |
| `inputFiles` | `string[]` | `[]` | Пути к отдельным SVG относительно конфига |
| `inputFolder` | `string` | `./icons` | Каталог с SVG относительно корня модуля |
| `inputFiles` | `string[]` | `[]` | Пути к отдельным SVG относительно корня модуля |
| `transform` | `TransformOptions` | Все включены | Настройки подготовки SVG |
| `generatedNotice` | `boolean` | `true` | Полное или короткое предупреждение в generated-файлах |
@@ -112,28 +110,41 @@ file-manager → FileManagerIcon
```text
app-icons/
├── .gitignore
├── index.ts
├── manifest.ts
├── svg-sprite.config.ts
── generated/
── .svg-sprites.manifest.json
├── react-component.tsx
── index.ts # необязательный пользовательский barrel
── .svg-sprite/
├── state.json
├── index.js
├── index.d.ts
├── icon-data.js
├── icon-data.d.ts
├── sprite.svg
├── styles.module.css
── types.ts
├── svg-sprite.manifest.js
── svg-sprite.manifest.d.ts
└── react/
├── react-component.js
├── react-component.d.ts
└── react-component.module.css
```
| Файл | Назначение |
|---|---|
| `index.ts` | Production exports компонента, props, стилей и имён иконок |
| `manifest.ts` | Debug metadata и URL asset для `SpriteViewer` |
| `generated/sprite.svg` | Собранный SVG-спрайт |
| `generated/react-component.tsx` | Типизированный React-компонент |
| `generated/styles.module.css` | Базовые стили и transitions |
| `generated/types.ts` | Runtime-список и union-тип имён |
| `generated/.svg-sprites.manifest.json` | Список файлов, которыми управляет генератор |
| `.svg-sprite/index.js` | Production exports компонента и runtime-списка имён |
| `.svg-sprite/index.d.ts` | Публичные декларации компонента, props, стилей и union-типа имён |
| `.svg-sprite/svg-sprite.manifest.js` | Debug metadata и URL asset для `SpriteViewer` |
| `.svg-sprite/sprite.svg` | Собранный SVG-спрайт |
| `.svg-sprite/react/react-component.js` | Runtime React-компонента без TypeScript и JSX |
| `.svg-sprite/react/react-component.d.ts` | Props, style и declaration React-компонента |
| `.svg-sprite/react/react-component.module.css` | Стили конкретной React-реализации |
| `.svg-sprite/icon-data.js` | Runtime-список имён и внутренние IDs |
| `.svg-sprite/*.d.ts` | TypeScript-декларации соответствующих JS-модулей |
| `.svg-sprite/state.json` | Mode, версия контракта и список управляемых файлов |
Генератор перезаписывает и удаляет только файлы со своим marker. Если в managed-пути находится пользовательский файл, генерация завершается ошибкой.
Генератор перезаписывает и удаляет только файлы со своим marker. Если в managed-пути находится пользовательский файл, генерация завершается ошибкой. Корневой `index.ts` генератору не принадлежит; при необходимости создайте пользовательский barrel:
```ts
export * from './.svg-sprite'
```
## React-компонент и TypeScript
@@ -224,12 +235,11 @@ editor-icons → EditorIcon → иконки редактора
## Форматы и способы отображения
Современные React- и Next.js-режимы создают формат `stack`. Legacy-режим поддерживает `stack` и `symbol`.
React- и Next.js-режимы создают формат `stack`.
| Формат | `<svg><use>` | `<img>` | CSS background |
|---|---:|---:|---:|
| `stack` | Да | Да | Да |
| `symbol` | Да | Нет | Нет |
### Generated-компонент
@@ -246,13 +256,13 @@ editor-icons → EditorIcon → иконки редактора
Vite:
```ts
import spriteUrl from './generated/sprite.svg?no-inline'
import spriteUrl from './.svg-sprite/sprite.svg?no-inline'
```
Webpack 5, Turbopack и Next.js:
```ts
const spriteUrl = new URL('./generated/sprite.svg', import.meta.url).href
const spriteUrl = new URL('./.svg-sprite/sprite.svg', import.meta.url).href
```
После получения URL используйте его в JSX:
@@ -277,7 +287,7 @@ SVG внутри `<img>` изолирован от CSS страницы. `color`
```css
.icon {
background: url('./generated/sprite.svg#search') center / contain no-repeat;
background: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
}
```
@@ -286,7 +296,7 @@ SVG внутри `<img>` изолирован от CSS страницы. `color`
```css
.icon {
background-color: currentColor;
mask: url('./generated/sprite.svg#search') center / contain no-repeat;
mask: url('./.svg-sprite/sprite.svg#search') center / contain no-repeat;
}
```
@@ -300,7 +310,7 @@ Generated-компонент передаёт SVG сборщику как отд
- Vite использует статический импорт с `?no-inline`;
- Webpack 5, Turbopack и Next.js используют `new URL(..., import.meta.url)`;
- SVG path-данные не сериализуются в generated TSX.
- SVG path-данные не сериализуются в generated JavaScript.
При стандартном именовании assets сборщик добавляет content hash:
@@ -325,7 +335,8 @@ HTTP cache headers, CDN и `Cache-Control` настраиваются прило
Чтобы отключить отдельную операцию:
```ts
export default defineNextSpriteConfig({
export default defineSpriteConfig({
mode: 'next@app/turbopack',
transform: {
removeSize: false,
replaceColors: false,
@@ -399,7 +410,7 @@ import { SpriteViewer } from '@gromlab/svg-sprites/react'
import type { SpriteManifestModule } from '@gromlab/svg-sprites/react'
const sources = import.meta.glob<SpriteManifestModule>(
'/src/**/svg-sprite/manifest.ts',
'/src/**/svg-sprite/.svg-sprite/svg-sprite.manifest.js',
)
export const IconsDebugPage = () => (
@@ -411,8 +422,8 @@ Webpack и Next.js:
```tsx
const sources = [
() => import('@/ui/app-icons/manifest'),
() => import('@/features/analytics/icons/manifest'),
() => import('@/ui/app-icons/.svg-sprite/svg-sprite.manifest.js'),
() => import('@/features/analytics/icons/.svg-sprite/svg-sprite.manifest.js'),
]
export const IconsDebugPage = () => (
@@ -447,9 +458,7 @@ Viewer показывает группы, поиск, `viewBox`, CSS-перем
Современный sprite-модуль создаёт локальный `.gitignore` для:
```text
/generated/
/index.ts
/manifest.ts
/.svg-sprite/
```
Локальный `.gitignore` следует один раз добавить в репозиторий. Он исключает остальные generated-файлы, поэтому генерацию нужно запускать перед командами, которые импортируют sprite-модуль:
@@ -457,7 +466,7 @@ Viewer показывает группы, поиск, `viewBox`, CSS-перем
```json
{
"scripts": {
"sprites": "svg-sprites --mode next@app/turbopack src/ui/app-icons",
"sprites": "svg-sprites src/ui/app-icons/svg-sprite.config.ts",
"predev": "npm run sprites",
"prebuild": "npm run sprites",
"pretypecheck": "npm run sprites"
@@ -467,18 +476,19 @@ Viewer показывает группы, поиск, `viewBox`, CSS-перем
CI должен устанавливать development dependencies и выполнять generation script до сборки или проверки типов.
Если в каталоге спрайта уже находится пользовательский `.gitignore`, `index.ts` или `manifest.ts`, генератор не перезапишет его. Переместите пользовательский файл или выберите отдельный каталог спрайта.
Если в каталоге спрайта уже находится пользовательский `.gitignore` либо пользовательский файл внутри `.svg-sprite`, генератор не перезапишет его. Корневой `index.ts` остаётся пользовательским и может переэкспортировать generated API.
## Диагностика
- Нет `index.ts`: запустите generation script до импорта модуля.
- Не найдена конфигурация: проверьте путь CLI и имя `svg-sprite.config.ts`.
- Нет `.svg-sprite/index.js`: запустите generation script до импорта generated-модуля.
- Не найден источник: передайте существующий config-файл или каталог sprite-модуля.
- Не указан mode: добавьте `mode` в config либо передайте `--mode`.
- Иконка отсутствует в типе: проверьте `inputFiles`, расширение `.svg` и уровень вложенности `inputFolder`.
- Конфликт имени: два разных SVG имеют одинаковый basename; переименуйте один файл.
- `Refusing to overwrite a user file`: в managed-пути находится файл без generated marker.
- Иконка не меняет цвет: используйте `<svg><use>` или generated-компонент и проверьте `replaceColors`.
- Webpack выдаёт неверный URL: проверьте Asset Modules, `output.publicPath` и SVG loaders.
- Viewer не видит спрайт: проверьте путь к `manifest.ts` и выполните генерацию до запуска приложения.
- Viewer не видит спрайт: проверьте путь к `.svg-sprite/svg-sprite.manifest.js` и выполните генерацию до запуска приложения.
- Build и mode не совпадают: используйте target, соответствующий фактическому сборщику.
Для собственного orchestration и низкоуровневой компиляции смотрите [Программный API](programmatic-api.md).