mirror of
https://github.com/gromlab-ru/svg-sprites.git
synced 2026-07-22 04:40:17 +03:00
docs: обновить документацию generated-контракта
- описаны единая конфигурация и exact modes - обновлена структура .svg-sprite - удалены материалы legacy pipeline - синхронизированы русская и английская версии skill
This commit is contained in:
@@ -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).
|
||||
@@ -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.
|
||||
@@ -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() {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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-модулей приложения.
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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 из несовместимого правила.
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user