mirror of
https://github.com/gromlab-ru/svg-sprites.git
synced 2026-07-22 04:40:17 +03:00
feat: добавить серверную генерацию спрайтов
This commit is contained in:
@@ -5,7 +5,7 @@ can also be used unchanged by AI skills.
|
||||
|
||||
The common format for JSON, JavaScript, and TypeScript config files is described in the [configuration guide](configuration.md).
|
||||
|
||||
## Quick Start Guides
|
||||
## Consumer Quick Starts
|
||||
|
||||
| Project | Exact mode | Guide |
|
||||
|---|---|---|
|
||||
@@ -39,12 +39,16 @@ The common format for JSON, JavaScript, and TypeScript config files is described
|
||||
| Next.js Pages Router + Turbopack | `next@pages/turbopack` | [Pages Router + Turbopack](guides/next-pages-turbopack.md) |
|
||||
| Next.js Pages Router + Webpack | `next@pages/webpack` | [Pages Router + Webpack](guides/next-pages-webpack.md) |
|
||||
|
||||
Every guide follows the same order:
|
||||
Every consumer guide follows the same order:
|
||||
|
||||
1. Generate the sprite through `npx` without adding the package to the project.
|
||||
2. Use the sprite in the application.
|
||||
3. Optionally add the Viewer for debugging and previews.
|
||||
|
||||
## Server-Side Generation
|
||||
|
||||
Use [`standalone@server`](guides/standalone-server.md) to generate a universal SVG sprite on a server or in CI/CD for all consumer modes.
|
||||
|
||||
## Reference
|
||||
|
||||
- [Configuration](configuration.md)
|
||||
|
||||
@@ -32,6 +32,7 @@ JSON works for most projects and does not require installing the package locally
|
||||
| Field | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `mode` | None | Exact mode matching the framework and bundler |
|
||||
| `source` | `local` | `local` for source SVG files or `remote` for a `standalone@server` manifest |
|
||||
| `name` | Kebab-case module directory name; for `svg-sprite` and `svg-sprites`, the parent directory name | Sprite name; in modes with a component, it also determines the component and type names |
|
||||
| `description` | None | Description used in types and the Viewer |
|
||||
| `input` | `./icons` | Directory, SVG file, glob pattern, or array of sources |
|
||||
@@ -40,6 +41,45 @@ JSON works for most projects and does not require installing the package locally
|
||||
|
||||
Paths and glob patterns in `input` are resolved relative to the config file's directory. A pattern prefixed with `!` excludes matches.
|
||||
|
||||
## Remotely built sprite
|
||||
|
||||
A consumer config for a server manifest only contains the mode, source, and input:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "react@vite",
|
||||
"source": "remote",
|
||||
"input": "https://assets.example/releases/app/svg-sprite.manifest.json"
|
||||
}
|
||||
```
|
||||
|
||||
`input` accepts one HTTP(S) URL or local manifest path. The name, description,
|
||||
transforms, and generated notice come from the manifest. The generator downloads
|
||||
and verifies the matching SVG profile before the adapter creates its normal local
|
||||
components, types, and bundler asset.
|
||||
|
||||
## Server build
|
||||
|
||||
`standalone@server` combines local paths/globs with HTTP(S) SVG descriptors:
|
||||
|
||||
```js
|
||||
export default {
|
||||
mode: 'standalone@server',
|
||||
name: 'app',
|
||||
input: [
|
||||
'./icons/**/*.svg',
|
||||
{
|
||||
name: 'remote-logo',
|
||||
url: 'https://assets.example/logo.svg',
|
||||
},
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
The mode creates two content-addressed SVG profiles and `svg-sprite.manifest.json`.
|
||||
`sha256` is optional for HTTP inputs; when present, it must be the expected 64-character
|
||||
hexadecimal SHA-256 digest and the build verifies the received bytes.
|
||||
|
||||
## JavaScript
|
||||
|
||||
A JavaScript config default-exports a plain object:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Quick Start Guides
|
||||
|
||||
## Consumer Applications
|
||||
|
||||
- `standalone`: [bare standalone](standalone.md)
|
||||
- `standalone@vite`: [standalone with Vite](standalone-vite.md)
|
||||
- `standalone@webpack`: [standalone with Webpack](standalone-webpack.md)
|
||||
@@ -29,3 +31,7 @@
|
||||
- `next@app/webpack`: [App Router with Webpack](next-app-webpack.md)
|
||||
- `next@pages/turbopack`: [Pages Router with Turbopack](next-pages-turbopack.md)
|
||||
- `next@pages/webpack`: [Pages Router with Webpack](next-pages-webpack.md)
|
||||
|
||||
## Server-Side Generation
|
||||
|
||||
- `standalone@server`: [generate a universal sprite on the server](standalone-server.md)
|
||||
|
||||
113
docs/en/guides/standalone-server.md
Normal file
113
docs/en/guides/standalone-server.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Universal SVG Sprite Generated on a Server
|
||||
|
||||
Generate a universal SVG sprite in CI or a server worker for applications that use different frameworks and bundlers.
|
||||
|
||||
## Generate the sprite
|
||||
|
||||
You do not need to install the package in the worker.
|
||||
|
||||
### 1. Prepare the workspace
|
||||
|
||||
Place the source SVGs in the current workspace's `icons` directory:
|
||||
|
||||
```text
|
||||
.
|
||||
└── icons/
|
||||
├── search.svg
|
||||
└── settings.svg
|
||||
```
|
||||
|
||||
Each filename without the extension becomes an icon name.
|
||||
|
||||
### 2. Run generation
|
||||
|
||||
Pass the mode, sprite name, and SVG path through the CLI:
|
||||
|
||||
```bash
|
||||
npx --yes @gromlab/svg-sprites \
|
||||
--mode standalone@server \
|
||||
--name app \
|
||||
--input './icons/**/*.svg' \
|
||||
.
|
||||
```
|
||||
|
||||
This worker workflow does not need a config file. The result appears in `./.svg-sprite`:
|
||||
|
||||
```text
|
||||
.
|
||||
├── icons/
|
||||
│ ├── search.svg
|
||||
│ └── settings.svg
|
||||
└── .svg-sprite/
|
||||
├── sprite.<content-hash>.svg
|
||||
├── sprite-root-viewbox.<content-hash>.svg
|
||||
└── svg-sprite.manifest.json
|
||||
```
|
||||
|
||||
### 3. Publish the result
|
||||
|
||||
Upload the contents of `.svg-sprite` to a dedicated S3 bucket directory:
|
||||
|
||||
```bash
|
||||
aws s3 sync ./.svg-sprite/ s3://my-bucket/app-icons/
|
||||
```
|
||||
|
||||
The same directory can be served through a CDN. The public URL does not contain a `.svg-sprite` segment:
|
||||
|
||||
```text
|
||||
https://cdn.example.com/app-icons/
|
||||
├── sprite.<content-hash>.svg
|
||||
├── sprite-root-viewbox.<content-hash>.svg
|
||||
└── svg-sprite.manifest.json
|
||||
```
|
||||
|
||||
You can also run `standalone@server` through a JSON, JavaScript, or TypeScript config. A config is useful for persistent settings, local SVGs from several directories, and SVGs loaded over HTTP(S).
|
||||
|
||||
## Use the sprite
|
||||
|
||||
Create a regular config in the consumer application. For example, with React and Vite:
|
||||
|
||||
```text
|
||||
src/app-icons/
|
||||
├── index.ts
|
||||
└── svg-sprite.config.json
|
||||
```
|
||||
|
||||
Set the consumer mode and the CDN manifest URL:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "react@vite",
|
||||
"source": "remote",
|
||||
"input": "https://cdn.example.com/app-icons/svg-sprite.manifest.json"
|
||||
}
|
||||
```
|
||||
|
||||
Add a user-owned entry point:
|
||||
|
||||
```ts
|
||||
// src/app-icons/index.ts
|
||||
export * from './.svg-sprite/index.js'
|
||||
```
|
||||
|
||||
Run normal generation:
|
||||
|
||||
```bash
|
||||
npx --yes @gromlab/svg-sprites src/app-icons/svg-sprite.config.json
|
||||
```
|
||||
|
||||
Then use the generated component exactly as with a sprite built from local SVGs:
|
||||
|
||||
```tsx
|
||||
import { AppIcon } from './app-icons'
|
||||
|
||||
export function SearchButton() {
|
||||
return <AppIcon icon="search" aria-label="Search" />
|
||||
}
|
||||
```
|
||||
|
||||
The same CDN manifest works with all 29 consumer modes. Each one preserves the native API of its selected framework and bundler.
|
||||
|
||||
## Debug and preview
|
||||
|
||||
`standalone@server` does not create a separate icon preview page. Connect the published sprite to a consumer application and open it in SpriteViewer: the remote set appears in the same way as a local one.
|
||||
@@ -30,7 +30,8 @@ result.manifestPath
|
||||
Next.js modes additionally return `router` and `bundler`.
|
||||
For bare `standalone`, `target` is `static`; standalone bundler and React modes
|
||||
return `vite` or `webpack`; Next.js modes return their full exact mode as the
|
||||
target.
|
||||
target. `standalone@server` returns `server`; its `spritePath` identifies the
|
||||
standard content-addressed profile and `manifestPath` identifies the server manifest.
|
||||
|
||||
For static standalone mode, use `result.spritePath` in a build script to publish the
|
||||
SVG under an application URL:
|
||||
@@ -105,6 +106,11 @@ export default defineSpriteConfig({
|
||||
|
||||
`defineSpriteConfig` is an identity helper for TypeScript autocomplete. JavaScript can export the same object with `export default`, while JSON contains the object directly.
|
||||
|
||||
The public `ServerSvgInput`, `ServerSpriteManifest`, `ServerSpriteAsset`, and
|
||||
`SpriteCompileProfile` types describe `standalone@server` inputs and release data.
|
||||
A consumer uses the same API with `source: 'remote'` and one local path or HTTP(S)
|
||||
manifest URL in `input`.
|
||||
|
||||
## Specialized wrappers
|
||||
|
||||
The specialized functions are available as wrappers around `generateSprite`:
|
||||
|
||||
@@ -69,6 +69,7 @@ svg-sprites [options] <config-file-or-directory>
|
||||
| Static HTML / custom publishing | `standalone` |
|
||||
| Standalone + Vite | `standalone@vite` |
|
||||
| Standalone + Webpack 5 | `standalone@webpack` |
|
||||
| Server release | `standalone@server` |
|
||||
| React + Vite | `react@vite` |
|
||||
| React + Webpack 5 | `react@webpack` |
|
||||
| Vue + Vite | `vue@vite` |
|
||||
@@ -100,7 +101,7 @@ The config file may have any name and use the `.ts`, `.js`, or `.json` extension
|
||||
|
||||
When a directory is passed, all settings come from CLI options. When a config file is passed, CLI options override the file. The full order is `defaults → config → CLI`.
|
||||
|
||||
`--help` and `-h` print usage information without requiring a path. Generation options are `--mode`, `--name`, `--description`, repeatable `--input <path-or-glob>`, plus the `--remove-size`/`--no-remove-size`, `--replace-colors`/`--no-replace-colors`, `--add-transition`/`--no-add-transition`, and `--generated-notice`/`--no-generated-notice` pairs. Transform flags override individual fields, while supplying at least one `--input` replaces the complete config `input` value.
|
||||
`--help` and `-h` print usage information without requiring a path. Generation options are `--mode`, `--source <local|remote>`, `--name`, `--description`, repeatable `--input <path-or-glob>`, plus the `--remove-size`/`--no-remove-size`, `--replace-colors`/`--no-replace-colors`, `--add-transition`/`--no-add-transition`, and `--generated-notice`/`--no-generated-notice` pairs. Transform flags override individual fields, while supplying at least one `--input` replaces the complete config `input` value.
|
||||
|
||||
Quote CLI glob patterns with single quotes so the shell does not expand them before the generator receives them:
|
||||
|
||||
@@ -138,12 +139,20 @@ export default defineSpriteConfig({
|
||||
| Option | Type | Default | Purpose |
|
||||
|---|---|---|---|
|
||||
| `mode` | `SpriteMode` | None | Generation mode; may be supplied by CLI/API |
|
||||
| `source` | `local \| remote` | `local` | Source SVG files or a ready server manifest |
|
||||
| `name` | `string` | Derived from the directory | Sprite name; in modes with a component, it also determines the component and public type names |
|
||||
| `description` | `string` | None | Description for types and the debug manifest |
|
||||
| `input` | `string \| string[]` | `./icons` | SVG folders, files, and glob patterns relative to the config directory |
|
||||
| `input` | `SpriteInput \| SpriteInput[]` | `./icons` | Local SVG sources, server HTTP descriptors, or one remote manifest, depending on mode and source |
|
||||
| `transform` | `TransformOptions` | All enabled | SVG preparation settings |
|
||||
| `generatedNotice` | `boolean` | `true` | Full or abbreviated warning in generated files |
|
||||
|
||||
With `source: 'remote'`, `input` contains one local path or HTTP(S) URL to a
|
||||
manifest produced by `standalone@server`. A remote consumer config may contain
|
||||
only `mode`, `source`, and `input`: the name, description, transforms, and generated
|
||||
notice are verified and inherited from the server manifest. Generation downloads
|
||||
the profile required by the exact consumer mode and verifies its SHA-256 and byte
|
||||
length before codegen. There is no runtime network dependency on the server manifest.
|
||||
|
||||
### Sprite name
|
||||
|
||||
`name` is written in kebab-case and must start with an ASCII letter:
|
||||
@@ -176,6 +185,26 @@ Supported glob syntax includes:
|
||||
|
||||
Every positive source or pattern must find at least one SVG, otherwise generation fails. Duplicate paths are removed and the final file list is sorted deterministically. Different SVG files with the same basename remain a conflict because the basename defines the public icon name.
|
||||
|
||||
### Server SVG inputs
|
||||
|
||||
`standalone@server` accepts the same local strings plus HTTP(S) descriptors in its
|
||||
`input` array:
|
||||
|
||||
```ts
|
||||
{
|
||||
name: 'brand-logo',
|
||||
url: 'https://assets.example.com/brand-logo.svg',
|
||||
sha256: '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef',
|
||||
}
|
||||
```
|
||||
|
||||
`name` becomes the public icon name. `sha256` is optional and, when present, is
|
||||
checked against the downloaded bytes. URL credentials and active SVG content such
|
||||
as scripts, event handlers, `foreignObject`, or a doctype are rejected. One HTTP
|
||||
source is limited to 2 MiB, all combined sources to 25 MiB, and requests time out
|
||||
after 15 seconds. Local and HTTP entries share one namespace, so duplicate icon
|
||||
names fail generation.
|
||||
|
||||
## Generated module
|
||||
|
||||
After generation, a React or Next.js sprite directory looks like this:
|
||||
@@ -225,6 +254,20 @@ runtime asset and deployment-neutral manifest data:
|
||||
native generated Web Component with no external runtime dependencies. Bare
|
||||
`standalone` intentionally does not generate a JavaScript component.
|
||||
|
||||
`standalone@server` creates a publishable release without JavaScript runtime or
|
||||
`.gitignore`:
|
||||
|
||||
```text
|
||||
.svg-sprite/
|
||||
├── sprite.<content-hash>.svg
|
||||
├── sprite-root-viewbox.<content-hash>.svg
|
||||
└── svg-sprite.manifest.json
|
||||
```
|
||||
|
||||
The manifest identifies both compile profiles by relative `href`, full SHA-256,
|
||||
and byte length. Publish the complete directory atomically; consumers resolve each
|
||||
profile relative to the manifest URL or local manifest path.
|
||||
|
||||
The generator fully manages `.svg-sprite` and replaces the whole directory on every generation through a staged write with rollback on replacement failure. Any files added inside it are deleted during the next generation. Keep user-owned files alongside it, for example in a root `index.ts` barrel:
|
||||
|
||||
```ts
|
||||
|
||||
Reference in New Issue
Block a user