This commit is contained in:
2026-07-15 12:27:46 +03:00
parent ab7042001a
commit 44afec7cdb
35 changed files with 1056 additions and 1224 deletions

78
docs/ru/guides/AGENTS.md Normal file
View File

@@ -0,0 +1,78 @@
# Правила гайдов быстрого старта
## Цель
Гайд должен помочь читателю как можно быстрее создать SVG-спрайт и использовать его в своём приложении.
Спрайт является главным результатом. Компоненты и другие сгенерированные файлы описываются только как средства его использования.
## Область гайда
Каждый гайд посвящён одному exact mode.
В гайд включаются только действия и особенности, относящиеся к этому mode. Нельзя переносить в него поведение других сборщиков, фреймворков или modes.
Все технические утверждения необходимо проверять по реализации соответствующего adapter.
## Структура
Гайд состоит из трёх основных частей:
1. Генерация спрайта.
2. Использование спрайта.
3. Дебаг и превью через Viewer.
Первая строка после заголовка должна объяснять, что это инструкция по быстрому созданию SVG-спрайта и для какого приложения она предназначена.
## Примеры
Все примеры внутри гайда должны составлять один последовательный сценарий.
Пути, имена, команды, импорты и названия сгенерированных API должны соответствовать друг другу и фактическому результату генерации.
Во всех гайдах используются согласованные примеры:
- исходные SVG находятся в `assets/svg-icons`;
- спрайт создаётся в `assets/app-icons`;
- конфиг записывается в JSON;
- имя спрайта в конфиге — `app`.
## Зависимости
В разделе генерации нужно явно показать ключевое преимущество: для создания и использования спрайта пакет не требуется добавлять в зависимости проекта.
Viewer описывается отдельно как необязательный инструмент разработки. Установка или подключение пакета допускается только в разделе Viewer и только способом, подходящим текущему mode.
## Содержание
Гайд должен содержать только минимальный рабочий путь:
- структуру проекта;
- конфиг;
- команду генерации;
- автоматическую генерацию перед запуском и сборкой, если она необходима;
- подключение иконки;
- базовую настройку размера и цветов;
- подключение Viewer.
Особенности mode добавляются только тогда, когда без них пример не работает или работает неправильно.
## Технический шум
Не нужно описывать внутреннее устройство генератора, сгенерированных файлов и сборщика.
Не нужно перечислять альтернативные конфигурации, дополнительные API, редкие сценарии и ограничения, не относящиеся к быстрому старту.
Подробности должны оставаться в reference-документации.
## Стиль
Писать для пользователя, а не для разработчика библиотеки.
Использовать короткие, прямые и практические формулировки.
Сначала объяснять пользу или цель шага, затем показывать действие.
Не использовать воду, рекламные формулировки и технические термины, которые не помогают выполнить инструкцию.
Не начинать документ с перечисления сгенерированных компонентов или особенностей реализации.

View File

@@ -1,153 +1,108 @@
# Next.js App Router с Turbopack
# SVG-спрайт для Next.js App Router с Turbopack
Это автономный quick start для exact mode key `next@app/turbopack`: generated `IconsIcon` совместим с Server Components и asset pipeline Turbopack.
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с App Router и Turbopack.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
```text
src/sprite/
├── icons/
│ ├── check.svg
│ └── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
Минимальный plain config:
```ts
export default {
mode: 'next@app/turbopack',
name: 'icons',
```json
{
"mode": "next@app/turbopack",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Конфиг может быть `.ts`, `.js` с `default export` или `.json`.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
В CI зафиксируйте точную версию, например `@gromlab/svg-sprites@1.1.5`. Mode и команды Next должны указывать один bundler:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && next dev --turbopack",
"build": "npm run sprites && next build --turbopack",
"start": "next start",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "next dev --turbopack",
"prebuild": "npm run sprites",
"build": "next build --turbopack"
}
}
```
Не добавляйте одновременно `predev`/`prebuild` и явный `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Его `.d.ts` self-contained и не импортируют generator package.
## Использование спрайта
Значение `name: "app"` создаёт React-компонент `AppIcon`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Generated icon не содержит `'use client'`, поэтому его можно импортировать прямо в Server Component:
Используйте компонент в Server Component:
```tsx
// app/page.tsx
import { IconsIcon, iconsIconNames } from '../src/sprite'
import { AppIcon } from '../assets/app-icons'
export default function Page() {
return (
<main>
<IconsIcon
icon="check"
width={24}
height={24}
aria-label="Готово"
style={{ '--icon-color-1': '#16a34a' }}
/>
<span>{iconsIconNames.length} иконок</span>
</main>
<AppIcon
icon="check"
width={24}
height={24}
role="img"
aria-label="Готово"
style={{
color: '#334155',
'--icon-color-2': '#f59e0b',
}}
/>
)
}
```
Turbopack обрабатывает generated `new URL('../sprite.svg', import.meta.url).href` и выпускает внешний hashed asset. Не добавляйте Client Component boundary только ради `IconsIcon`.
Для `AppIcon` не нужен `'use client'`. Turbopack сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
## 2. Дебаг и превью
## Дебаг и превью
Viewer необязателен и нужен только для debug/preview:
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
```bash
npm install --save-dev @gromlab/svg-sprites
```
Viewer интерактивен, поэтому создайте для него отдельный Client Component:
Создайте Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
```tsx
// app/icons-debug/sprite-viewer.tsx
'use client'
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('../../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
] as const
export function AppSpriteViewer() {
export function SvgSpriteViewer() {
return <SpriteViewer sources={sources} title="Иконки проекта" />
}
```
Server page импортирует только эту boundary:
Создайте маршрут `app/svg-sprite/page.tsx`:
```tsx
// app/icons-debug/page.tsx
import { AppSpriteViewer } from './sprite-viewer'
import { notFound } from 'next/navigation'
export default function IconsDebugPage() {
return <AppSpriteViewer />
import { SvgSpriteViewer } from './SvgSpriteViewer'
export default function SvgSpritePage() {
if (process.env.NODE_ENV !== 'development') notFound()
return <SvgSpriteViewer />
}
```
Viewer не входит в production icon runtime и не нужен обычным страницам с `IconsIcon`.
## 3. Типизация конфига
После локальной установки package используйте helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'next@app/turbopack',
name: 'icons',
})
```
Возможен и type-only import `SpriteConfig` с `satisfies SpriteConfig`.
Без package добавьте локальный type в config:
```ts
type LocalSpriteConfig = {
mode: 'next@app/turbopack'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'next@app/turbopack',
name: 'icons',
} satisfies LocalSpriteConfig
```
Exact literal защищает от смешивания App Router и других bundler contracts.
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.

View File

@@ -1,151 +1,108 @@
# Next.js App Router с Webpack
# SVG-спрайт для Next.js App Router с Webpack
Это автономный quick start для exact mode key `next@app/webpack`: generated `IconsIcon` совместим с Server Components и Webpack pipeline Next.js.
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с App Router и Webpack.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
```text
src/sprite/
├── icons/
│ ├── check.svg
│ └── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
Минимальный plain config:
```ts
export default {
mode: 'next@app/webpack',
name: 'icons',
```json
{
"mode": "next@app/webpack",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Также поддерживаются `.js` с `default export` и `.json`.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
В CI замените `latest` точной версией, например `@gromlab/svg-sprites@1.1.5`. Exact Next commands для этого mode:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && next dev --webpack",
"build": "npm run sprites && next build --webpack",
"start": "next start",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "next dev --webpack",
"prebuild": "npm run sprites",
"build": "next build --webpack"
}
}
```
Не сочетайте явный `npm run sprites` с `predev` или `prebuild`. `.svg-sprite` generated и не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated declarations self-contained и не зависят от `@gromlab/svg-sprites`.
## Использование спрайта
Значение `name: "app"` создаёт React-компонент `AppIcon`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Production usage в Server Component:
Используйте компонент в Server Component:
```tsx
// app/page.tsx
import { IconsIcon, iconsIconNames } from '../src/sprite'
import { AppIcon } from '../assets/app-icons'
export default function Page() {
return (
<main>
<IconsIcon
icon="check"
width={24}
height={24}
aria-label="Готово"
style={{ '--icon-color-1': '#16a34a' }}
/>
<span>{iconsIconNames.length} иконок</span>
</main>
<AppIcon
icon="check"
width={24}
height={24}
role="img"
aria-label="Готово"
style={{
color: '#334155',
'--icon-color-2': '#f59e0b',
}}
/>
)
}
```
Generated component не содержит `'use client'`. Next Webpack обрабатывает `new URL('../sprite.svg', import.meta.url).href` и публикует отдельный SVG asset; не переписывайте этот URL и не переносите sprite в `public` вручную.
Для `AppIcon` не нужен `'use client'`. Next.js сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
## 2. Дебаг и превью
## Дебаг и превью
Viewer необязателен. Для debug/preview установите package:
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
```bash
npm install --save-dev @gromlab/svg-sprites
```
App Router требует отдельную Client Component boundary для Viewer:
Создайте Client Component `app/svg-sprite/SvgSpriteViewer.tsx`:
```tsx
// app/icons-debug/sprite-viewer.tsx
'use client'
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('../../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('../../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
] as const
export function AppSpriteViewer() {
export function SvgSpriteViewer() {
return <SpriteViewer sources={sources} title="Иконки проекта" />
}
```
Создайте маршрут `app/svg-sprite/page.tsx`:
```tsx
// app/icons-debug/page.tsx
import { AppSpriteViewer } from './sprite-viewer'
import { notFound } from 'next/navigation'
export default function IconsDebugPage() {
return <AppSpriteViewer />
import { SvgSpriteViewer } from './SvgSpriteViewer'
export default function SvgSpritePage() {
if (process.env.NODE_ENV !== 'development') notFound()
return <SvgSpriteViewer />
}
```
Статический loader позволяет Webpack связать manifest и emitted SVG. Viewer не входит в production runtime `IconsIcon`.
## 3. Типизация конфига
При локально установленном package используйте helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'next@app/webpack',
name: 'icons',
})
```
Другой package-вариант: type-only import `SpriteConfig` и `satisfies SpriteConfig`.
Без package вставьте локальный type прямо в config:
```ts
type LocalSpriteConfig = {
mode: 'next@app/webpack'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'next@app/webpack',
name: 'icons',
} satisfies LocalSpriteConfig
```
Локальный exact literal исключает случайную генерацию Turbopack или Pages Router output.
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.

View File

@@ -1,140 +1,98 @@
# Next.js Pages Router с Turbopack
# SVG-спрайт для Next.js Pages Router с Turbopack
Это автономный quick start для exact mode key `next@pages/turbopack`: generated `IconsIcon` работает при SSR, SSG и клиентских переходах Pages Router.
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с Pages Router и Turbopack.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
```text
src/sprite/
├── icons/
│ ├── check.svg
│ └── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
Минимальный plain config:
```ts
export default {
mode: 'next@pages/turbopack',
name: 'icons',
```json
{
"mode": "next@pages/turbopack",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Конфиг также может быть `.js` с `default export` или `.json`.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
Для CI зафиксируйте точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact commands должны сохранять Turbopack и для dev, и для production build:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && next dev --turbopack",
"build": "npm run sprites && next build --turbopack",
"start": "next start",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "next dev --turbopack",
"prebuild": "npm run sprites",
"build": "next build --turbopack"
}
}
```
Не добавляйте `predev`/`prebuild`, если scripts уже явно вызывают `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated `.d.ts` self-contained и не импортируют generator package.
## Использование спрайта
Значение `name: "app"` создаёт React-компонент `AppIcon`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Production usage на обычной page:
Используйте компонент на странице:
```tsx
// pages/index.tsx
import { IconsIcon, iconsIconNames } from '../src/sprite'
import { AppIcon } from '../assets/app-icons'
export default function Page() {
return (
<main>
<IconsIcon
icon="check"
width={24}
height={24}
aria-label="Готово"
style={{ '--icon-color-1': '#16a34a' }}
/>
<span>{iconsIconNames.length} иконок</span>
</main>
<AppIcon
icon="check"
width={24}
height={24}
role="img"
aria-label="Готово"
style={{
color: '#334155',
'--icon-color-2': '#f59e0b',
}}
/>
)
}
```
Компонент одинаково работает с `getServerSideProps`, `getStaticProps` и client navigation. Turbopack разрешает generated `new URL('../sprite.svg', import.meta.url).href` в отдельный hashed asset.
Компонент работает с SSR, SSG и клиентскими переходами. Turbopack сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
## 2. Дебаг и превью
## Дебаг и превью
Viewer необязателен и нужен только для debug/preview:
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
```bash
npm install --save-dev @gromlab/svg-sprites
```
В Pages Router Viewer можно использовать прямо в page, без отдельной App Router Client Component boundary:
Создайте страницу `pages/svg-sprite.tsx`:
```tsx
// pages/icons-debug.tsx
import type { GetStaticProps } from 'next'
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
] as const
export default function IconsDebugPage() {
export default function SvgSpritePage() {
return <SpriteViewer sources={sources} title="Иконки проекта" />
}
export const getStaticProps: GetStaticProps = () =>
process.env.NODE_ENV === 'development'
? { props: {} }
: { notFound: true }
```
Оставляйте эту page только во внутреннем debug-разделе. Viewer не входит в production icon runtime `IconsIcon`.
## 3. Типизация конфига
Если package установлен локально, используйте helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'next@pages/turbopack',
name: 'icons',
})
```
Альтернатива: type-only import `SpriteConfig` и объект `satisfies SpriteConfig`.
Без package добавьте copy-paste type в config:
```ts
type LocalSpriteConfig = {
mode: 'next@pages/turbopack'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'next@pages/turbopack',
name: 'icons',
} satisfies LocalSpriteConfig
```
Exact literal не позволяет незаметно смешать Pages Router с App Router или Webpack output.
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.

View File

@@ -1,140 +1,98 @@
# Next.js Pages Router с Webpack
# SVG-спрайт для Next.js Pages Router с Webpack
Это автономный quick start для exact mode key `next@pages/webpack`: generated `IconsIcon` работает в Pages Router и публикует SVG через Webpack pipeline Next.js.
Инструкция по быстрому созданию SVG-спрайта в приложении Next.js с Pages Router и Webpack.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
```text
src/sprite/
├── icons/
│ ├── check.svg
│ └── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
Минимальный plain config:
```ts
export default {
mode: 'next@pages/webpack',
name: 'icons',
```json
{
"mode": "next@pages/webpack",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Поддерживаются `.ts`, `.js` с `default export` и `.json` configs.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
В CI замените `latest` на точную проверенную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Next commands для Webpack:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && next dev --webpack",
"build": "npm run sprites && next build --webpack",
"start": "next start",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "next dev --webpack",
"prebuild": "npm run sprites",
"build": "next build --webpack"
}
}
```
Не дублируйте эти вызовы через `predev`, `prebuild` или `pretypecheck`. `.svg-sprite` generated и не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated declarations self-contained и не требуют `@gromlab/svg-sprites`.
## Использование спрайта
Значение `name: "app"` создаёт React-компонент `AppIcon`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Production usage:
Используйте компонент на странице:
```tsx
// pages/index.tsx
import { IconsIcon, iconsIconNames } from '../src/sprite'
import { AppIcon } from '../assets/app-icons'
export default function Page() {
return (
<main>
<IconsIcon
icon="check"
width={24}
height={24}
aria-label="Готово"
style={{ '--icon-color-1': '#16a34a' }}
/>
<span>{iconsIconNames.length} иконок</span>
</main>
<AppIcon
icon="check"
width={24}
height={24}
role="img"
aria-label="Готово"
style={{
color: '#334155',
'--icon-color-2': '#f59e0b',
}}
/>
)
}
```
Компонент поддерживает SSR, SSG и клиентские переходы. Next Webpack преобразует generated `new URL('../sprite.svg', import.meta.url).href` во внешний hashed asset; не конструируйте URL спрайта вручную.
Компонент работает с SSR, SSG и клиентскими переходами. Next.js сам добавляет `sprite.svg` в итоговую сборку, поэтому переносить его в `public` не нужно.
## 2. Дебаг и превью
## Дебаг и превью
Viewer необязателен. Устанавливайте package только для debug/preview:
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
```bash
npm install --save-dev @gromlab/svg-sprites
```
Pages Router позволяет разместить Viewer непосредственно в page без отдельной App Router boundary:
Создайте страницу `pages/svg-sprite.tsx`:
```tsx
// pages/icons-debug.tsx
import type { GetStaticProps } from 'next'
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('../src/sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
] as const
export default function IconsDebugPage() {
export default function SvgSpritePage() {
return <SpriteViewer sources={sources} title="Иконки проекта" />
}
export const getStaticProps: GetStaticProps = () =>
process.env.NODE_ENV === 'development'
? { props: {} }
: { notFound: true }
```
Статический loader даёт Webpack точный manifest module и связанный SVG asset. Не импортируйте Viewer из production pages, если preview там не нужен; runtime `IconsIcon` от него независим.
## 3. Типизация конфига
После локальной установки package доступен helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'next@pages/webpack',
name: 'icons',
})
```
Также можно применить `satisfies SpriteConfig` с type-only импортом `SpriteConfig`.
Без package вставьте локальный type прямо в config:
```ts
type LocalSpriteConfig = {
mode: 'next@pages/webpack'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'next@pages/webpack',
name: 'icons',
} satisfies LocalSpriteConfig
```
Такой exact literal выявляет ошибочный выбор App Router или Turbopack ещё при проверке config.
Запустите `npm run dev` и откройте `/svg-sprite`. В production маршрут вернёт 404.

View File

@@ -1,141 +1,115 @@
# React-компонент для Vite
# SVG-спрайт для React на Vite
Это автономный quick start для exact mode key `react@vite`: генератор создаёт типизированный `IconsIcon`, а Vite публикует отдельный SVG asset.
Инструкция по быстрому созданию SVG-спрайта в React-приложении на Vite.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
```text
src/sprite/
├── icons/
│ ├── check.svg
│ └── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
Минимальный plain config:
```ts
export default {
mode: 'react@vite',
name: 'icons',
```json
{
"mode": "react@vite",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Вместо `.ts` можно использовать `.js` с `default export` или `.json`.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
В CI замените `latest` на точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Vite commands:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && vite",
"build": "npm run sprites && tsc --noEmit && vite build",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "vite",
"prebuild": "npm run sprites",
"build": "tsc --noEmit && vite build"
}
}
```
Не добавляйте `predev`, `prebuild` или `pretypecheck`, если соответствующие scripts уже явно запускают `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated declarations self-contained: они описывают компонент и manifest без импорта `@gromlab/svg-sprites`.
## Использование спрайта
Пользовательский barrel возвращает generated API:
Значение `name: "app"` создаёт React-компонент `AppIcon`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Production usage:
Используйте компонент в приложении:
```tsx
import { IconsIcon, iconsIconNames } from './sprite'
import { AppIcon } from '../assets/app-icons'
export function SaveButton() {
export function SaveIcon() {
return (
<button type="button">
<IconsIcon
icon="check"
width={24}
height={24}
aria-hidden="true"
style={{ '--icon-color-1': '#16a34a' }}
/>
Сохранить
</button>
<AppIcon
icon="check"
width={24}
height={24}
role="img"
aria-label="Готово"
style={{
color: '#334155',
'--icon-color-2': '#f59e0b',
}}
/>
)
}
console.log(iconsIconNames)
```
Prop `icon` является union имён исходных файлов. Vite автоматически обрабатывает generated CSS Module и импорт `sprite.svg?no-inline`; query запрещает inline и заставляет Vite выпустить отдельный hashed SVG asset. Если TypeScript не знает Vite asset imports, добавьте `/// <reference types="vite/client" />` в `src/vite-env.d.ts`.
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
## 2. Дебаг и превью
Vite сам подключает стили компонента и добавляет `sprite.svg` в итоговую сборку.
Viewer необязателен и нужен только для debug/preview. Установите package отдельно:
## Дебаг и превью
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
```bash
npm install --save-dev @gromlab/svg-sprites
```
Используйте React bridge со статическим массивом loaders:
Создайте `svg-sprite.html` в корне проекта:
```html
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Иконки проекта</title>
</head>
<body>
<!-- React-корень Viewer для дебага и превью SVG-спрайта -->
<div id="svg-sprite-viewer"></div>
<!-- Подключение создаваемого ниже скрипта дебаггера -->
<script type="module" src="/src/svg-sprite-debug.tsx"></script>
</body>
</html>
```
Создайте `src/svg-sprite-debug.tsx`:
```tsx
import { createRoot } from 'react-dom/client'
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('./sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
] as const
export function IconsDebugPage() {
return <SpriteViewer sources={sources} title="Иконки проекта" />
}
createRoot(document.getElementById('svg-sprite-viewer')!).render(
<SpriteViewer sources={sources} title="Иконки проекта" />,
)
```
Строковый путь в `import()` должен указывать на generated JS manifest. Держите страницу за debug-маршрутом; `SpriteViewer` не входит в production runtime `IconsIcon`.
Запустите `npm run dev` и откройте `/svg-sprite.html`.
## 3. Типизация конфига
Если package установлен локально, используйте helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'react@vite',
name: 'icons',
})
```
Также можно импортировать `SpriteConfig` только как type и написать объект `satisfies SpriteConfig`.
Без package добавьте локальный type прямо в config:
```ts
type LocalSpriteConfig = {
mode: 'react@vite'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'react@vite',
name: 'icons',
} satisfies LocalSpriteConfig
```
Локальный type проверяет только этот exact mode и не создаёт runtime-зависимость.
Стандартная production-сборка Vite использует только `index.html` и не включает страницу Viewer.

View File

@@ -1,141 +1,126 @@
# React-компонент для Webpack 5
# SVG-спрайт для React на Webpack 5
Это автономный quick start для exact mode key `react@webpack`: generated `IconsIcon` использует Webpack 5 Asset Modules и CSS Modules.
Инструкция по быстрому созданию SVG-спрайта в React-приложении на Webpack 5.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
```text
src/sprite/
├── icons/
│ ├── check.svg
│ └── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
Минимальный plain config:
```ts
export default {
mode: 'react@webpack',
name: 'icons',
```json
{
"mode": "react@webpack",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Поддерживаются `.ts`, `.js` с `default export` и `.json` configs.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
В CI замените `latest` на точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Webpack commands:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && webpack serve --mode development",
"build": "npm run sprites && webpack --mode production",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "webpack serve --mode development",
"prebuild": "npm run sprites",
"build": "webpack --mode production"
}
}
```
Не сочетайте эти явные вызовы с `predev`/`prebuild`: иначе генерация задублируется. `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated `.d.ts` self-contained и не импортируют generator package.
## Использование спрайта
Значение `name: "app"` создаёт React-компонент `AppIcon`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Production usage:
Используйте компонент в приложении:
```tsx
import { IconsIcon, iconsIconNames } from './sprite'
import { AppIcon } from '../assets/app-icons'
export function SaveButton() {
export function SaveIcon() {
return (
<button type="button">
<IconsIcon
icon="check"
width={24}
height={24}
aria-hidden="true"
style={{ '--icon-color-1': '#16a34a' }}
/>
Сохранить
</button>
<AppIcon
icon="check"
width={24}
height={24}
role="img"
aria-label="Готово"
style={{
color: '#334155',
'--icon-color-2': '#f59e0b',
}}
/>
)
}
console.log(iconsIconNames)
```
Generated component получает URL через `new URL('../sprite.svg', import.meta.url).href`. Webpack 5 должен обработать SVG как Asset Module. Исключите generated `sprite.svg` из `@svgr/webpack`, inline/raw loaders и других общих SVG rules либо задайте для него `type: 'asset/resource'`.
Свойство `icon` принимает имена исходных SVG без расширения. Монохромная иконка наследует `color`, а цвета многоцветной переопределяются через `--icon-color-N`.
Компонент импортирует `react-component.module.css`. Webpack config должен обрабатывать `*.module.css` через `css-loader` с CSS Modules и `style-loader` или `MiniCssExtractPlugin`. Для TypeScript при необходимости добавьте декларацию `declare module '*.module.css'`.
Компонент использует CSS Modules. Если проект ещё не обрабатывает их с default export, добавьте правило в `webpack.config.js`:
## 2. Дебаг и превью
```js
{
test: /\.module\.css$/i,
use: [
'style-loader',
{
loader: 'css-loader',
options: { modules: { namedExport: false } },
},
],
}
```
Viewer необязателен. Устанавливайте package только для debug/preview:
Webpack 5 сам добавляет `sprite.svg` в итоговую сборку.
## Дебаг и превью
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки.
Установите Viewer:
```bash
npm install --save-dev @gromlab/svg-sprites
```
Webpack не использует `import.meta.glob`; передайте статический loader:
Создайте entry `src/svg-sprite-debug.tsx`:
```tsx
import { createRoot } from 'react-dom/client'
import { SpriteViewer } from '@gromlab/svg-sprites/react'
const sources = [
() => import('./sprite/.svg-sprite/svg-sprite.manifest.js'),
() => import('../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'),
] as const
export function IconsDebugPage() {
return <SpriteViewer sources={sources} title="Иконки проекта" />
}
const container = document.createElement('div')
document.body.append(container)
createRoot(container).render(
<SpriteViewer sources={sources} title="Иконки проекта" />,
)
```
Webpack создаст chunk manifest и разрешит его SVG через тот же Asset Modules pipeline. Viewer держите только в debug route; production `IconsIcon` от него не зависит.
Добавьте скрипт к основному entry только в development-режиме. Сохраните остальные настройки `webpack.config.js`:
## 3. Типизация конфига
С локально установленным package доступен helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'react@webpack',
name: 'icons',
```js
export default (_env, argv) => ({
// Остальные настройки Webpack.
entry: [
'./src/main.tsx',
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.tsx'] : []),
],
})
```
Эквивалентная проверка: type-only import `SpriteConfig` и `satisfies SpriteConfig`.
Без package используйте copy-paste type в config:
```ts
type LocalSpriteConfig = {
mode: 'react@webpack'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'react@webpack',
name: 'icons',
} satisfies LocalSpriteConfig
```
Локальный literal не разрешит случайно выбрать Vite или Next mode.
Запустите `npm run dev`. Viewer появится на основной странице приложения и не попадёт в production-сборку.

View File

@@ -1,151 +1,114 @@
# Нативный icon Web Component с Vite
# SVG-спрайт для Vite без фреймворка
Это автономный quick start для exact mode key `standalone@vite`: generated facade регистрирует `<icons-icon>` и отдаёт SVG в asset pipeline Vite.
Инструкция по быстрому созданию SVG-спрайта в приложении на Vite без фреймворка.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
Рекомендуемая структура держит конфиг и иконки рядом:
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
```text
src/sprite/
├── icons/
├── check.svg
└── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Минимальный plain config:
```ts
export default {
mode: 'standalone@vite',
name: 'icons',
```json
{
"mode": "standalone@vite",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Конфиг также может быть `.js` с `default export` или `.json`.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
В CI замените `latest` на точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact dev/build commands для Vite:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && vite",
"build": "npm run sprites && vite build",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "vite",
"prebuild": "npm run sprites",
"build": "vite build"
}
}
```
Не добавляйте одновременно `predev`/`prebuild` и явный `npm run sprites` в этих scripts. `.svg-sprite` является generated-каталогом и не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Generated `.d.ts` self-contained и не импортируют `@gromlab/svg-sprites`.
## Использование спрайта
Верните facade через пользовательский barrel:
Значение `name: "app"` создаёт элемент `<app-icon>`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Production entry регистрирует native Web Component:
Зарегистрируйте элемент в `src/main.ts`:
```ts
import { defineIconsIconElement, iconsIconNames } from './sprite'
import { defineAppIconElement } from '../assets/app-icons'
import './style.css'
defineIconsIconElement()
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
<icons-icon icon="check" role="img" aria-label="Готово"></icons-icon>
`
console.log(iconsIconNames)
defineAppIconElement()
```
Generated facade импортирует `sprite.svg?no-inline`: Vite автоматически выпускает отдельный hashed SVG asset и не превращает его в data URL. TypeScript-проекту при необходимости добавьте стандартные Vite types:
Используйте иконку в HTML:
```ts
/// <reference types="vite/client" />
```html
<app-icon icon="check" role="img" aria-label="Готово"></app-icon>
```
Размер по умолчанию равен `1em`, поэтому компонент удобно масштабировать через `font-size`. Цвет задаётся через `color` и generated custom properties:
Файл `check.svg` доступен как `icon="check"`. Размер и цвета настраиваются через CSS:
```css
icons-icon {
app-icon {
font-size: 24px;
color: #334155;
--icon-color-2: #f59e0b;
}
```
## 2. Дебаг и превью
Монохромная иконка наследует `color`, а цвета многоцветной иконки переопределяются через `--icon-color-N`. Нужные переменные показывает Viewer.
Viewer необязателен и нужен только для debug/preview. Установите его отдельно:
Vite сам добавит `sprite.svg` в итоговую сборку. Копировать его в `public` не нужно.
## Дебаг и превью
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки и устанавливается отдельно:
```bash
npm install --save-dev @gromlab/svg-sprites
```
Зарегистрируйте Viewer и передайте generated JS manifest через свойство `sources`:
Создайте `svg-sprite.html` в корне проекта:
```html
<!doctype html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Иконки проекта</title>
</head>
<body>
<!-- Компонент Viewer для дебага и превью SVG-спрайта -->
<gromlab-sprite-viewer viewer-title="Иконки проекта"></gromlab-sprite-viewer>
<!-- Подключение создаваемого ниже скрипта дебаггера -->
<script type="module" src="/src/svg-sprite-debug.ts"></script>
</body>
</html>
```
Создайте `src/svg-sprite-debug.ts`:
```ts
import '@gromlab/svg-sprites/viewer/element'
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
import spriteManifest from './sprite/.svg-sprite/svg-sprite.manifest.js'
document.querySelector<HTMLDivElement>('#app')!.insertAdjacentHTML(
'beforeend',
'<gromlab-sprite-viewer></gromlab-sprite-viewer>',
)
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
viewer.viewerTitle = 'Иконки проекта'
viewer.sources = [spriteManifest]
```
Расположите этот код только в debug entry или внутреннем маршруте. Viewer не входит в production runtime `<icons-icon>`.
Запустите `npm run dev` и откройте `/svg-sprite.html`.
## 3. Типизация конфига
При локально установленном package используйте helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'standalone@vite',
name: 'icons',
})
```
Альтернатива с package: `import type { SpriteConfig }` и объект `satisfies SpriteConfig`.
Без package скопируйте локальный type прямо в config:
```ts
type LocalSpriteConfig = {
mode: 'standalone@vite'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'standalone@vite',
name: 'icons',
} satisfies LocalSpriteConfig
```
Локальный type ограничивает `mode` одним exact literal и ничего не загружает во время генерации.
Viewer не требуется для работы `<app-icon>` и не подключается к основному коду приложения.

View File

@@ -1,145 +1,111 @@
# Нативный icon Web Component с Webpack 5
# SVG-спрайт для Webpack 5 без фреймворка
Это автономный quick start для exact mode key `standalone@webpack`: generated facade предоставляет `<icons-icon>`, а Webpack 5 публикует SVG через Asset Modules.
Инструкция по быстрому созданию SVG-спрайта в приложении на Webpack 5 без фреймворка.
## 1. Генерация спрайта
## Генерация спрайта
Главное преимущество: генератор не нужно устанавливать и добавлять в `package.json`. `npx` временно скачивает CLI, а generated production runtime не импортирует `@gromlab/svg-sprites`.
Выберите папку для спрайта. В примере используется `assets/app-icons`, а исходные SVG находятся в `assets/svg-icons`.
```text
src/sprite/
├── icons/
│ ├── check.svg
│ └── warning.svg
├── index.ts
└── svg-sprite.config.ts
```
Создайте конфиг `assets/app-icons/svg-sprite.config.json`:
Минимальный config рядом с `icons/`:
```ts
export default {
mode: 'standalone@webpack',
name: 'icons',
```json
{
"mode": "standalone@webpack",
"name": "app",
"input": "../svg-icons/**/*.svg"
}
```
Если `input` не указан, SVG читаются из `./icons` относительно конфига. Поддерживаются также `.js` с `default export` и `.json`.
Путь в `input` считается от папки с конфигом.
```bash
npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts
```
Для CI закрепите точную версию, например `@gromlab/svg-sprites@1.1.5`. Exact Webpack commands:
Добавьте команды генерации в `package.json`. Сгенерированные файлы по умолчанию исключены из Git, поэтому `predev` и `prebuild` пересобирают спрайт перед каждым запуском и сборкой:
```json
{
"scripts": {
"sprites": "npx --yes --package=@gromlab/svg-sprites@latest svg-sprites src/sprite/svg-sprite.config.ts",
"dev": "npm run sprites && webpack serve --mode development",
"build": "npm run sprites && webpack --mode production",
"typecheck": "npm run sprites && tsc --noEmit"
"sprites": "npx --yes @gromlab/svg-sprites assets/app-icons/svg-sprite.config.json",
"predev": "npm run sprites",
"dev": "webpack serve --mode development",
"prebuild": "npm run sprites",
"build": "webpack --mode production"
}
}
```
Не дублируйте запуск через `predev`/`prebuild`, если scripts уже явно вызывают `npm run sprites`. Generated `.svg-sprite` не коммитится. Generated локальный `.gitignore`, который исключает этот каталог, нужно добавить в Git один раз. Его declarations self-contained и не требуют `@gromlab/svg-sprites`.
## Использование спрайта
Значение `name: "app"` создаёт элемент `<app-icon>`.
Создайте точку входа `assets/app-icons/index.ts`:
```ts
// src/sprite/index.ts
export * from './.svg-sprite/index.js'
```
Production usage:
Зарегистрируйте элемент в основном entry приложения:
```ts
import { defineIconsIconElement, iconsIconNames } from './sprite'
import { defineAppIconElement } from '../assets/app-icons'
import './style.css'
defineIconsIconElement()
document.querySelector<HTMLDivElement>('#app')!.innerHTML = `
<icons-icon icon="check" role="img" aria-label="Готово"></icons-icon>
`
console.log(iconsIconNames)
defineAppIconElement()
```
Generated facade использует `new URL('./sprite.svg', import.meta.url).href`. Webpack 5 Asset Modules выпускают отдельный asset; его итоговый URL учитывает `output.publicPath` и `assetModuleFilename`.
Используйте иконку в HTML:
Если проект использует `@svgr/webpack`, `svg-inline-loader`, `raw-loader` или общий SVG rule, исключите `src/sprite/.svg-sprite/sprite.svg` из этого правила. Generated SVG должен обрабатываться как `asset/resource`, а не как React-компонент или inline source.
```html
<app-icon icon="check" role="img" aria-label="Готово"></app-icon>
```
Размер Web Component по умолчанию `1em`; управляйте им и цветами обычным CSS:
Файл `check.svg` доступен как `icon="check"`. Размер и цвета настраиваются через CSS:
```css
icons-icon {
app-icon {
font-size: 24px;
color: #334155;
--icon-color-2: #f59e0b;
}
```
## 2. Дебаг и превью
Монохромная иконка наследует `color`, а цвета многоцветной иконки переопределяются через `--icon-color-N`. Нужные переменные показывает Viewer.
Viewer необязателен. Для debug/preview установите package как dev dependency:
Webpack 5 сам добавит `sprite.svg` в итоговую сборку.
## Дебаг и превью
Viewer показывает все иконки на одной странице, позволяет проверить их отображение, изменить цвета и посмотреть связанные CSS-переменные. Он нужен только для разработки.
Установите Viewer:
```bash
npm install --save-dev @gromlab/svg-sprites
```
Подключите element entry и generated JS manifest:
Создайте entry `src/svg-sprite-debug.ts`:
```ts
import '@gromlab/svg-sprites/viewer/element'
import type { SpriteViewerElement } from '@gromlab/svg-sprites/viewer'
import spriteManifest from './sprite/.svg-sprite/svg-sprite.manifest.js'
import spriteManifest from '../assets/app-icons/.svg-sprite/svg-sprite.manifest.js'
document.querySelector<HTMLDivElement>('#app')!.insertAdjacentHTML(
'beforeend',
'<gromlab-sprite-viewer></gromlab-sprite-viewer>',
)
const viewer = document.querySelector<SpriteViewerElement>('gromlab-sprite-viewer')!
const viewer = document.createElement('gromlab-sprite-viewer') as SpriteViewerElement
viewer.viewerTitle = 'Иконки проекта'
viewer.sources = [spriteManifest]
document.body.append(viewer)
```
Webpack свяжет manifest с тем же emitted SVG asset. Оставляйте Viewer только в debug entry: production `<icons-icon>` от него не зависит.
Добавьте скрипт к основному entry только в development-режиме. Сохраните остальные настройки `webpack.config.js`:
## 3. Типизация конфига
После локальной установки package можно использовать helper:
```ts
import { defineSpriteConfig } from '@gromlab/svg-sprites'
export default defineSpriteConfig({
mode: 'standalone@webpack',
name: 'icons',
```js
export default (_env, argv) => ({
// Остальные настройки Webpack.
entry: [
'./src/main.ts',
...(argv.mode === 'development' ? ['./src/svg-sprite-debug.ts'] : []),
],
})
```
Либо импортируйте только `SpriteConfig` как type и примените `satisfies SpriteConfig`.
Запустите `npm run dev`. Viewer появится на основной странице приложения.
Без package добавьте copy-paste type в сам config:
```ts
type LocalSpriteConfig = {
mode: 'standalone@webpack'
name?: string
description?: string
input?: string | string[]
transform?: {
removeSize?: boolean
replaceColors?: boolean
addTransition?: boolean
}
generatedNotice?: boolean
}
export default {
mode: 'standalone@webpack',
name: 'icons',
} satisfies LocalSpriteConfig
```
Этот вариант сохраняет проверку exact mode без runtime import и без записи generator package в проект.
Viewer добавляется только в development-сборку и не попадает в production.