vite-plugin-layer
v0.0.2
Published
Cross-framework Vite plugin bringing Nuxt-Layer-style shared-base + extends/override to React, Svelte and Vue.
Downloads
298
Maintainers
Readme
vite-plugin-layer
Nuxt-Layer-style shared base layer + per-project inherit & override, as a
cross-framework Vite plugin. React / Svelte / Vue (and any framework Vite supports)
can all extends the same base.
Three pillars, all driven from one layer() call:
| Capability | Mechanism |
| :-- | :-- |
| Config inheritance / override merge | c12 + defu → virtual:layer-config |
| Shared code reuse (#base/*) | Vite alias |
| Auto-import (utils/ without import) | unimport (React out of the box; Svelte/Vue via a flag) |
Install
pnpm add -D vite-plugin-layervite is a peer dependency (>=5).
Usage
Declare a base layer's defaults in layer.config.ts, then have each app extends it.
// layers/base/layer.config.ts
import { defineLayerConfig } from 'vite-plugin-layer'
export default defineLayerConfig({
app: { name: 'Base Layer', poweredBy: 'vite-plugin-layer' },
apiBase: 'https://api.example.com',
})// app vite.config.ts
import { defineConfig } from 'vite'
import { layer } from 'vite-plugin-layer'
export default defineConfig(async () => ({
plugins: [
framework(), // react() / svelte() / vue()
await layer({
extends: ['../layers/base'], // also supports c12 remote sources like 'github:org/base'
app: { name: 'My App' }, // overrides the same-named field in base
}),
],
}))Config can instead live in the app's own layer.config.ts — then layer() reads it with no args.
Framework auto-import
Names under base/utils/* are usable without an import. React works out of the box.
Svelte and Vue need their imports injected into <script> / <script setup> before compile,
so opt in with a flag — it's an enforce: 'pre' plugin, ordered automatically:
// svelte
plugins: [svelte(), await layer({ svelte: true })]
// vue
plugins: [vue(), await layer({ vue: true })]
// react — no flag needed
plugins: [react(), await layer()]In your app code
import { request } from '@layer/base/http' // package name — same string you extends
import config from 'virtual:layer-config' // merged config across the extends chain
// formatMoney, formatDate, ... — auto-imported from base/utils, no import lineWhen a layer is a package, use its package name for both extends and imports (same string,
no alias). extends accepts a path, a package name, or a remote github: source. For package-name
extends, give the layer "main": "./layer.config.ts" so c12 can resolve its config.
For path-only layers the plugin provides fallback aliases: #base (nearest parent) and
#layers/<name> (name from layer.config.ts name → package.json name → directory), mapped via
tsconfig.json paths.
For TypeScript, add the ambient types in tsconfig.json:
{
"compilerOptions": {
"types": ["vite/client", "vite-plugin-layer/client"],
"paths": { "#base/*": ["../layers/base/*"] }
}
}Options
layer(options):
| Option | Default | Description |
| :-- | :-- | :-- |
| extends | — | Base layer(s): relative/absolute path or c12 remote source (github:org/base) |
| app / other fields | — | Inline config, merged over the extends chain (highest priority) |
| cwd | process.cwd() | Starting directory for resolution |
| configName | 'layer' | Config file name → layer.config.ts |
| autoImportDirs | ['utils', 'composables'] | Directory names scanned into auto-import |
| autoImportsDts | 'auto-imports.d.ts' | Path for the generated d.ts, or false to disable. e.g. 'types/layer-imports.d.ts' |
| svelte / vue | false | Enable the framework's auto-import adapter (true or {}) |
Typed virtual:layer-config
Augment LayerConfigRuntime once in your app (same pattern as Vite's ImportMetaEnv) for precise types:
declare module 'vite-plugin-layer' {
interface LayerConfigRuntime {
app: { name: string }
apiBase: string
}
}
export {}defineLayerConfig is generic too, so the config in layer.config.ts keeps its literal types.
First-time type generation
The auto-import .d.ts is generated by dev/build. To make it exist on a fresh checkout (before the
first dev/build — e.g. for CI typecheck or opening the editor), run the bundled CLI on install:
{
"scripts": {
"prepare": "vite-plugin-layer prepare"
}
}No flags needed — the CLI resolves your Vite config and reads the layer() options straight from
it (extends chain, custom autoImportsDts path, vue), so it works for any app as-is. --cwd <dir>
targets a different directory. The same thing is available programmatically as prepare(options)
(same options as layer()) for setups without a Vite config.
License
MIT
