https://github.com/martinbspheroid/vite-static-assets-plugin
Better DX for working with static files in Vite projects using Typescript
https://github.com/martinbspheroid/vite-static-assets-plugin
assets assets-management files public vite vitejs
Last synced: 5 months ago
JSON representation
Better DX for working with static files in Vite projects using Typescript
- Host: GitHub
- URL: https://github.com/martinbspheroid/vite-static-assets-plugin
- Owner: MartinBspheroid
- Created: 2025-02-11T22:13:06.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-04-07T09:04:24.000Z (6 months ago)
- Last Synced: 2025-05-07T06:45:14.363Z (5 months ago)
- Topics: assets, assets-management, files, public, vite, vitejs
- Language: TypeScript
- Homepage:
- Size: 169 KB
- Stars: 10
- Watchers: 1
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
![]()
# Vite Static Assets Plugin
A Vite plugin that **automatically scans your static assets directory**, generates a **type-safe TypeScript module** with all asset paths, **directory-aware types**, and a helper function to get asset URLs. It validates asset references during build and updates live during development.
---
## Features
- 🚀 **Automatic Recursive Scanning:** Scans a directory (default: `public`) for all static assets.
- 🛡 **Type-Safe API:** Generates a union type `StaticAssetPath` of all valid asset paths.
- 📁 **Directory-Aware Types:** Generates `StaticAssetDirectory` and a powerful `FilesInFolder` generic for directory-specific asset typing.
- 🔗 **Helper Function:** Provides `staticAssets()` to get the URL for an asset, with runtime validation.
- 🛠 **Highly Configurable:** Customize directory, output file, ignore patterns, debounce, directory depth, empty directory handling, leading slash, and more.
- 🔄 **Live Updates:** Watches the directory in development mode and regenerates types on changes.
- 🧭 **Validation:** Validates asset references and directory references during build, with detailed error messages.
- ⚡ **Fast:** Minimal overhead, optimized for large projects.
Built withBun – the ultra-fast JavaScript runtime & toolkit
---
## Usage
Import the generated function and types:
```typescript
import { staticAssets, StaticAssetPath, StaticAssetDirectory, FilesInFolder } from './static-assets';// Use the helper function
const logoUrl = staticAssets('images/logo.svg');// Type-safe variables
const assetPath: StaticAssetPath = 'fonts/roboto.woff2';const dir: StaticAssetDirectory = 'images/';
// Type-safe list of files directly inside 'icons/brands/'
type Icons = FilesInFolder<'icons/brands/'>;
// use Icons type in your code
type Brands = {
icon: Icons,
name: string
}
// Create a list of brands with their icons and names
// get autocompletion and type checking!
const brands: Brands[] = [
{
icon: "icons/brands/coke.svg",
name: "Coke"
},
{
icon: "icons/brands/pepsi.svg",
name: "Pepsi"
},
{
icon: "icons/brands/rc-cola.svg",
name: "RC Cola"
},
{
icon: "icons/brands/dr-pepper.svg",
name: "Dr Pepper"
},
]```
---
## Installation
```bash
# npm
npm install --save-dev vite-static-assets-plugin# yarn
yarn add -D vite-static-assets-plugin# bun
bun add -d vite-static-assets-plugin# pnpm
pnpm add -D vite-static-assets-plugin
```---
## Setup and Configuration
Add the plugin to your Vite config:
### vite.config.ts
```typescript
import { defineConfig } from 'vite';
import staticAssetsPlugin from 'vite-static-assets-plugin';export default defineConfig({
plugins: [
staticAssetsPlugin({
// Optional configuration (defaults shown):
directory: 'public',
outputFile: 'src/static-assets.ts',
ignore: ['.DS_Store'],
debounce: 200,
enableDirectoryTypes: true,
maxDirectoryDepth: 5,
allowEmptyDirectories: false,
addLeadingSlash: true,
})
]
});
```---
## Generated TypeScript Module
The plugin generates a TypeScript file (default: `src/static-assets.ts`) containing:
### `StaticAssetPath`
A union of all asset paths:
```typescript
export type StaticAssetPath =
'images/logo.svg' |
'images/banner.jpg' |
'fonts/roboto.woff2';
```### `StaticAssetDirectory`
A union of all directories containing assets, including `'.'` for the root:
```typescript
export type StaticAssetDirectory =
'.' |
'fonts/' |
'images/' ;
```### `FilesInFolder`
A generic type representing **only the files directly inside** a directory:
```typescript
// Example: all files directly inside 'images/' (not nested)
type ImageFiles = FilesInFolder<'images/'>;
// 'logo.svg' | 'banner.jpg'
```### `staticAssets(path)`
A function that returns the URL for an asset, with validation:
```typescript
export function staticAssets(path: StaticAssetPath): string;
```If you pass an invalid path, it throws an error at runtime and TypeScript will catch it at compile time.
---
Use it in your components:
```tsx
![]()
```---
## Framework Agnostic
![]()
![]()
![]()
![]()
![]()
![]()
![]()
Works with **any** frontend framework that uses Vite: React, Vue, Svelte, Angular, Solid, Lit, and more.
---
## Plugin Options
| Option | Type | Default | Description |
|--------------------------|-----------------|---------------------------|--------------------------------------------------------------------------------------------------|
| `directory` | `string` | `'public'` | Directory to scan for static assets |
| `outputFile` | `string` | `'src/static-assets.ts'` | Path to generate the TypeScript module |
| `ignore` | `string[]` | `['.DS_Store']` | Glob patterns to ignore |
| `debounce` | `number` | `200` | Debounce time (ms) for file watcher events |
| `enableDirectoryTypes` | `boolean` | `true` | Generate directory-aware types (`StaticAssetDirectory`, `FilesInFolder`) |
| `maxDirectoryDepth` | `number` | `5` | Maximum directory nesting level for directory type generation |
| `allowEmptyDirectories` | `boolean` | `false` | Allow referencing empty directories in validation |
| `addLeadingSlash` | `boolean` | `true` | Add a leading slash to generated asset URLs |---
## How It Works
1. **Scans** the specified directory recursively, ignoring patterns.
2. **Generates** a TypeScript file with:
- `StaticAssetPath` union of all asset paths.
- `StaticAssetDirectory` union of directories.
- `FilesInFolder` generic.
- `staticAssets()` function.
3. **Watches** the directory in development mode, regenerating on changes.
4. **Validates** asset references and directory references during build.
5. **Throws errors** with detailed info if assets or directories are missing.---
## Error Handling
- If you reference a missing asset in `staticAssets()`, the plugin throws a build-time error with details (even if you're skipping TS typechecking before build).
- If you reference a directory (via `FilesInFolder` or in code) that is empty or missing, it throws an error **unless** `allowEmptyDirectories: true`.
- Errors include the file path, missing asset/directory, and suggestions.
- Please note that this message is shown in case you **actually skip TS typechecking before build**. In case you're not typechecking before build (which is recommended), the error will be thrown at build time and you'll see the full error message in the terminal.
---## TypeScript Integration
- The generated file is **TypeScript-ready** (as long as you set `outputFile` in your `vite.config.ts` to folder that is visible to your project).
- Enjoy **auto-completion**, **type checking**, and **refactoring support** for your static assets.---
## Development
### Testing
This project uses **Vitest**:
```bash
# Run all tests
npm test# Watch mode
npm run test:watch# Coverage
npm run test:coverage
```Tests are in `packages/plugin/tests/` and cover core functions and plugin behavior.
---
## License
MIT
---
## Contributing
Contributions, issues, and feature requests are welcome! Please open an issue or pull request.