feat: Complete fleet — 94 skills across 10+ domains
Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
5
skills/vite/GENERATION.md
Normal file
5
skills/vite/GENERATION.md
Normal file
@@ -0,0 +1,5 @@
|
||||
# Generation Info
|
||||
|
||||
- **Source:** `sources/vite`
|
||||
- **Git SHA:** `c47015eba4f0de255218c35769628d87152216ca`
|
||||
- **Generated:** 2026-01-31
|
||||
72
skills/vite/SKILL.md
Normal file
72
skills/vite/SKILL.md
Normal file
@@ -0,0 +1,72 @@
|
||||
---
|
||||
name: vite
|
||||
description: Vite build tool configuration, plugin API, SSR, and Vite 8 Rolldown migration. Use when working with Vite projects, vite.config.ts, Vite plugins, or building libraries/SSR apps with Vite.
|
||||
metadata:
|
||||
author: Anthony Fu
|
||||
version: "2026.1.31"
|
||||
source: Generated from https://github.com/vitejs/vite, scripts at https://github.com/antfu/skills
|
||||
---
|
||||
|
||||
# Vite
|
||||
|
||||
> Based on Vite 8 beta (Rolldown-powered). Vite 8 uses Rolldown bundler and Oxc transformer.
|
||||
|
||||
Vite is a next-generation frontend build tool with fast dev server (native ESM + HMR) and optimized production builds.
|
||||
|
||||
## Preferences
|
||||
|
||||
- Use TypeScript: prefer `vite.config.ts`
|
||||
- Always use ESM, avoid CommonJS
|
||||
|
||||
## Core
|
||||
|
||||
| Topic | Description | Reference |
|
||||
|-------|-------------|-----------|
|
||||
| Configuration | `vite.config.ts`, `defineConfig`, conditional configs, `loadEnv` | [core-config](references/core-config.md) |
|
||||
| Features | `import.meta.glob`, asset queries (`?raw`, `?url`), `import.meta.env`, HMR API | [core-features](references/core-features.md) |
|
||||
| Plugin API | Vite-specific hooks, virtual modules, plugin ordering | [core-plugin-api](references/core-plugin-api.md) |
|
||||
|
||||
## Build & SSR
|
||||
|
||||
| Topic | Description | Reference |
|
||||
|-------|-------------|-----------|
|
||||
| Build & SSR | Library mode, SSR middleware mode, `ssrLoadModule`, JavaScript API | [build-and-ssr](references/build-and-ssr.md) |
|
||||
|
||||
## Advanced
|
||||
|
||||
| Topic | Description | Reference |
|
||||
|-------|-------------|-----------|
|
||||
| Environment API | Vite 6+ multi-environment support, custom runtimes | [environment-api](references/environment-api.md) |
|
||||
| Rolldown Migration | Vite 8 changes: Rolldown bundler, Oxc transformer, config migration | [rolldown-migration](references/rolldown-migration.md) |
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### CLI Commands
|
||||
|
||||
```bash
|
||||
vite # Start dev server
|
||||
vite build # Production build
|
||||
vite preview # Preview production build
|
||||
vite build --ssr # SSR build
|
||||
```
|
||||
|
||||
### Common Config
|
||||
|
||||
```ts
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [],
|
||||
resolve: { alias: { '@': '/src' } },
|
||||
server: { port: 3000, proxy: { '/api': 'http://localhost:8080' } },
|
||||
build: { target: 'esnext', outDir: 'dist' },
|
||||
})
|
||||
```
|
||||
|
||||
### Official Plugins
|
||||
|
||||
- `@vitejs/plugin-vue` - Vue 3 SFC support
|
||||
- `@vitejs/plugin-vue-jsx` - Vue 3 JSX
|
||||
- `@vitejs/plugin-react` - React with Oxc/Babel
|
||||
- `@vitejs/plugin-react-swc` - React with SWC
|
||||
- `@vitejs/plugin-legacy` - Legacy browser support
|
||||
238
skills/vite/references/build-and-ssr.md
Normal file
238
skills/vite/references/build-and-ssr.md
Normal file
@@ -0,0 +1,238 @@
|
||||
---
|
||||
name: vite-build-ssr
|
||||
description: Vite library mode and SSR configuration
|
||||
---
|
||||
|
||||
# Build and SSR
|
||||
|
||||
## Library Mode
|
||||
|
||||
Build a library for distribution:
|
||||
|
||||
```ts
|
||||
// vite.config.ts
|
||||
import { resolve } from 'node:path'
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
lib: {
|
||||
entry: resolve(import.meta.dirname, 'lib/main.ts'),
|
||||
name: 'MyLib',
|
||||
fileName: 'my-lib',
|
||||
},
|
||||
rolldownOptions: {
|
||||
external: ['vue', 'react'],
|
||||
output: {
|
||||
globals: {
|
||||
vue: 'Vue',
|
||||
react: 'React',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Multiple Entries
|
||||
|
||||
```ts
|
||||
build: {
|
||||
lib: {
|
||||
entry: {
|
||||
'my-lib': resolve(import.meta.dirname, 'lib/main.ts'),
|
||||
secondary: resolve(import.meta.dirname, 'lib/secondary.ts'),
|
||||
},
|
||||
name: 'MyLib',
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Output Formats
|
||||
|
||||
- Single entry: `es` and `umd`
|
||||
- Multiple entries: `es` and `cjs`
|
||||
|
||||
### Package.json Setup
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-lib",
|
||||
"type": "module",
|
||||
"files": ["dist"],
|
||||
"main": "./dist/my-lib.umd.cjs",
|
||||
"module": "./dist/my-lib.js",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/my-lib.js",
|
||||
"require": "./dist/my-lib.umd.cjs"
|
||||
},
|
||||
"./style.css": "./dist/my-lib.css"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Multi-Page App
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rolldownOptions: {
|
||||
input: {
|
||||
main: resolve(import.meta.dirname, 'index.html'),
|
||||
nested: resolve(import.meta.dirname, 'nested/index.html'),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## SSR Development
|
||||
|
||||
### Middleware Mode
|
||||
|
||||
Use Vite as middleware in a custom server:
|
||||
|
||||
```ts
|
||||
import express from 'express'
|
||||
import { createServer as createViteServer } from 'vite'
|
||||
|
||||
const app = express()
|
||||
|
||||
const vite = await createViteServer({
|
||||
server: { middlewareMode: true },
|
||||
appType: 'custom',
|
||||
})
|
||||
|
||||
app.use(vite.middlewares)
|
||||
|
||||
app.use('*all', async (req, res, next) => {
|
||||
const url = req.originalUrl
|
||||
|
||||
// 1. Read and transform index.html
|
||||
let template = await fs.readFile('index.html', 'utf-8')
|
||||
template = await vite.transformIndexHtml(url, template)
|
||||
|
||||
// 2. Load server entry
|
||||
const { render } = await vite.ssrLoadModule('/src/entry-server.ts')
|
||||
|
||||
// 3. Render app
|
||||
const appHtml = await render(url)
|
||||
|
||||
// 4. Inject into template
|
||||
const html = template.replace('<!--ssr-outlet-->', appHtml)
|
||||
|
||||
res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
|
||||
})
|
||||
|
||||
app.listen(5173)
|
||||
```
|
||||
|
||||
### SSR Build
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build:client": "vite build --outDir dist/client",
|
||||
"build:server": "vite build --outDir dist/server --ssr src/entry-server.ts"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The `--ssr` flag:
|
||||
- Externalizes dependencies by default
|
||||
- Outputs for Node.js consumption
|
||||
|
||||
### SSR Manifest
|
||||
|
||||
Generate asset mapping for preload hints:
|
||||
|
||||
```bash
|
||||
vite build --outDir dist/client --ssrManifest
|
||||
```
|
||||
|
||||
Creates `dist/client/.vite/ssr-manifest.json` mapping module IDs to chunks.
|
||||
|
||||
### SSR Externals
|
||||
|
||||
Control which deps get bundled vs externalized:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
ssr: {
|
||||
noExternal: ['some-package'], // Bundle this dep
|
||||
external: ['another-package'], // Externalize this dep
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Conditional Logic
|
||||
|
||||
```ts
|
||||
if (import.meta.env.SSR) {
|
||||
// Server-only code (tree-shaken from client)
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript API
|
||||
|
||||
### createServer
|
||||
|
||||
```ts
|
||||
import { createServer } from 'vite'
|
||||
|
||||
const server = await createServer({
|
||||
configFile: false,
|
||||
root: import.meta.dirname,
|
||||
server: { port: 1337 },
|
||||
})
|
||||
|
||||
await server.listen()
|
||||
server.printUrls()
|
||||
```
|
||||
|
||||
### build
|
||||
|
||||
```ts
|
||||
import { build } from 'vite'
|
||||
|
||||
await build({
|
||||
root: './project',
|
||||
build: { outDir: 'dist' },
|
||||
})
|
||||
```
|
||||
|
||||
### preview
|
||||
|
||||
```ts
|
||||
import { preview } from 'vite'
|
||||
|
||||
const previewServer = await preview({
|
||||
preview: { port: 8080, open: true },
|
||||
})
|
||||
previewServer.printUrls()
|
||||
```
|
||||
|
||||
### resolveConfig
|
||||
|
||||
```ts
|
||||
import { resolveConfig } from 'vite'
|
||||
|
||||
const config = await resolveConfig({}, 'build')
|
||||
```
|
||||
|
||||
### loadEnv
|
||||
|
||||
```ts
|
||||
import { loadEnv } from 'vite'
|
||||
|
||||
const env = loadEnv('development', process.cwd(), '')
|
||||
// Loads all env vars (empty prefix = no filtering)
|
||||
```
|
||||
|
||||
<!--
|
||||
Source references:
|
||||
- https://vite.dev/guide/build
|
||||
- https://vite.dev/guide/ssr
|
||||
- https://vite.dev/guide/api-javascript
|
||||
-->
|
||||
162
skills/vite/references/core-config.md
Normal file
162
skills/vite/references/core-config.md
Normal file
@@ -0,0 +1,162 @@
|
||||
---
|
||||
name: vite-config
|
||||
description: Vite configuration patterns using vite.config.ts
|
||||
---
|
||||
|
||||
# Vite Configuration
|
||||
|
||||
## Basic Setup
|
||||
|
||||
```ts
|
||||
// vite.config.ts
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
// config options
|
||||
})
|
||||
```
|
||||
|
||||
Vite auto-resolves `vite.config.ts` from project root. Supports ES modules syntax regardless of `package.json` type.
|
||||
|
||||
## Conditional Config
|
||||
|
||||
Export a function to access command and mode:
|
||||
|
||||
```ts
|
||||
export default defineConfig(({ command, mode, isSsrBuild, isPreview }) => {
|
||||
if (command === 'serve') {
|
||||
return { /* dev config */ }
|
||||
} else {
|
||||
return { /* build config */ }
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
- `command`: `'serve'` during dev, `'build'` for production
|
||||
- `mode`: `'development'` or `'production'` (or custom via `--mode`)
|
||||
|
||||
## Async Config
|
||||
|
||||
```ts
|
||||
export default defineConfig(async ({ command, mode }) => {
|
||||
const data = await fetchSomething()
|
||||
return { /* config */ }
|
||||
})
|
||||
```
|
||||
|
||||
## Using Environment Variables in Config
|
||||
|
||||
`.env` files are loaded **after** config resolution. Use `loadEnv` to access them in config:
|
||||
|
||||
```ts
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
|
||||
export default defineConfig(({ mode }) => {
|
||||
// Load env files from cwd, include all vars (empty prefix)
|
||||
const env = loadEnv(mode, process.cwd(), '')
|
||||
|
||||
return {
|
||||
define: {
|
||||
__APP_ENV__: JSON.stringify(env.APP_ENV),
|
||||
},
|
||||
server: {
|
||||
port: env.APP_PORT ? Number(env.APP_PORT) : 5173,
|
||||
},
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## Key Config Options
|
||||
|
||||
### resolve.alias
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': '/src',
|
||||
'~': '/src',
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### define (Global Constants)
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
define: {
|
||||
__APP_VERSION__: JSON.stringify('1.0.0'),
|
||||
__API_URL__: 'window.__backend_api_url',
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Values must be JSON-serializable or single identifiers. Non-strings auto-wrapped with `JSON.stringify`.
|
||||
|
||||
### plugins
|
||||
|
||||
```ts
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [vue()],
|
||||
})
|
||||
```
|
||||
|
||||
Plugins array is flattened; falsy values ignored.
|
||||
|
||||
### server.proxy
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:3000',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ''),
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### build.target
|
||||
|
||||
Default: Baseline Widely Available browsers. Customize:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
build: {
|
||||
target: 'esnext', // or 'es2020', ['chrome90', 'firefox88']
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## TypeScript Intellisense
|
||||
|
||||
For plain JS config files:
|
||||
|
||||
```js
|
||||
/** @type {import('vite').UserConfig} */
|
||||
export default {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Or use `satisfies`:
|
||||
|
||||
```ts
|
||||
import type { UserConfig } from 'vite'
|
||||
|
||||
export default {
|
||||
// ...
|
||||
} satisfies UserConfig
|
||||
```
|
||||
|
||||
<!--
|
||||
Source references:
|
||||
- https://vite.dev/config/
|
||||
- https://vite.dev/guide/
|
||||
-->
|
||||
205
skills/vite/references/core-features.md
Normal file
205
skills/vite/references/core-features.md
Normal file
@@ -0,0 +1,205 @@
|
||||
---
|
||||
name: vite-features
|
||||
description: Vite-specific import patterns and runtime features
|
||||
---
|
||||
|
||||
# Vite Features
|
||||
|
||||
## Glob Import
|
||||
|
||||
Import multiple modules matching a pattern:
|
||||
|
||||
```ts
|
||||
const modules = import.meta.glob('./dir/*.ts')
|
||||
// { './dir/foo.ts': () => import('./dir/foo.ts'), ... }
|
||||
|
||||
for (const path in modules) {
|
||||
modules[path]().then((mod) => {
|
||||
console.log(path, mod)
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### Eager Loading
|
||||
|
||||
```ts
|
||||
const modules = import.meta.glob('./dir/*.ts', { eager: true })
|
||||
// Modules loaded immediately, no dynamic import
|
||||
```
|
||||
|
||||
### Named Imports
|
||||
|
||||
```ts
|
||||
const modules = import.meta.glob('./dir/*.ts', { import: 'setup' })
|
||||
// Only imports the 'setup' export from each module
|
||||
|
||||
const defaults = import.meta.glob('./dir/*.ts', { import: 'default', eager: true })
|
||||
```
|
||||
|
||||
### Multiple Patterns
|
||||
|
||||
```ts
|
||||
const modules = import.meta.glob(['./dir/*.ts', './another/*.ts'])
|
||||
```
|
||||
|
||||
### Negative Patterns
|
||||
|
||||
```ts
|
||||
const modules = import.meta.glob(['./dir/*.ts', '!**/ignored.ts'])
|
||||
```
|
||||
|
||||
### Custom Queries
|
||||
|
||||
```ts
|
||||
const svgRaw = import.meta.glob('./icons/*.svg', { query: '?raw', import: 'default' })
|
||||
const svgUrls = import.meta.glob('./icons/*.svg', { query: '?url', import: 'default' })
|
||||
```
|
||||
|
||||
## Asset Import Queries
|
||||
|
||||
### URL Import
|
||||
|
||||
```ts
|
||||
import imgUrl from './img.png'
|
||||
// Returns resolved URL: '/src/img.png' (dev) or '/assets/img.2d8efhg.png' (build)
|
||||
```
|
||||
|
||||
### Explicit URL
|
||||
|
||||
```ts
|
||||
import workletUrl from './worklet.js?url'
|
||||
```
|
||||
|
||||
### Raw String
|
||||
|
||||
```ts
|
||||
import shaderCode from './shader.glsl?raw'
|
||||
```
|
||||
|
||||
### Inline/No-Inline
|
||||
|
||||
```ts
|
||||
import inlined from './small.png?inline' // Force base64 inline
|
||||
import notInlined from './large.png?no-inline' // Force separate file
|
||||
```
|
||||
|
||||
### Web Workers
|
||||
|
||||
```ts
|
||||
import Worker from './worker.ts?worker'
|
||||
const worker = new Worker()
|
||||
|
||||
// Or inline:
|
||||
import InlineWorker from './worker.ts?worker&inline'
|
||||
```
|
||||
|
||||
Preferred pattern using constructor:
|
||||
|
||||
```ts
|
||||
const worker = new Worker(new URL('./worker.ts', import.meta.url), {
|
||||
type: 'module',
|
||||
})
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
### Built-in Constants
|
||||
|
||||
```ts
|
||||
import.meta.env.MODE // 'development' | 'production' | custom
|
||||
import.meta.env.BASE_URL // Base URL from config
|
||||
import.meta.env.PROD // true in production
|
||||
import.meta.env.DEV // true in development
|
||||
import.meta.env.SSR // true when running in server
|
||||
```
|
||||
|
||||
### Custom Variables
|
||||
|
||||
Only `VITE_` prefixed vars exposed to client:
|
||||
|
||||
```
|
||||
# .env
|
||||
VITE_API_URL=https://api.example.com
|
||||
DB_PASSWORD=secret # NOT exposed to client
|
||||
```
|
||||
|
||||
```ts
|
||||
console.log(import.meta.env.VITE_API_URL) // works
|
||||
console.log(import.meta.env.DB_PASSWORD) // undefined
|
||||
```
|
||||
|
||||
### Mode-specific Files
|
||||
|
||||
```
|
||||
.env # always loaded
|
||||
.env.local # always loaded, gitignored
|
||||
.env.[mode] # only in specified mode
|
||||
.env.[mode].local # only in specified mode, gitignored
|
||||
```
|
||||
|
||||
### TypeScript Support
|
||||
|
||||
```ts
|
||||
// vite-env.d.ts
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_API_URL: string
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv
|
||||
}
|
||||
```
|
||||
|
||||
### HTML Replacement
|
||||
|
||||
```html
|
||||
<p>Running in %MODE%</p>
|
||||
<script>window.API = "%VITE_API_URL%"</script>
|
||||
```
|
||||
|
||||
## CSS Modules
|
||||
|
||||
Any `.module.css` file treated as CSS module:
|
||||
|
||||
```ts
|
||||
import styles from './component.module.css'
|
||||
element.className = styles.button
|
||||
```
|
||||
|
||||
With camelCase conversion:
|
||||
|
||||
```ts
|
||||
// .my-class -> myClass (if css.modules.localsConvention configured)
|
||||
import { myClass } from './component.module.css'
|
||||
```
|
||||
|
||||
## JSON Import
|
||||
|
||||
```ts
|
||||
import pkg from './package.json'
|
||||
import { version } from './package.json' // Named import with tree-shaking
|
||||
```
|
||||
|
||||
## HMR API
|
||||
|
||||
```ts
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.accept((newModule) => {
|
||||
// Handle update
|
||||
})
|
||||
|
||||
import.meta.hot.dispose((data) => {
|
||||
// Cleanup before module is replaced
|
||||
})
|
||||
|
||||
import.meta.hot.invalidate() // Force full reload
|
||||
}
|
||||
```
|
||||
|
||||
<!--
|
||||
Source references:
|
||||
- https://vite.dev/guide/features
|
||||
- https://vite.dev/guide/env-and-mode
|
||||
- https://vite.dev/guide/assets
|
||||
- https://vite.dev/guide/api-hmr
|
||||
-->
|
||||
235
skills/vite/references/core-plugin-api.md
Normal file
235
skills/vite/references/core-plugin-api.md
Normal file
@@ -0,0 +1,235 @@
|
||||
---
|
||||
name: vite-plugin-api
|
||||
description: Vite plugin authoring with Vite-specific hooks
|
||||
---
|
||||
|
||||
# Vite Plugin API
|
||||
|
||||
Vite plugins extend Rolldown's plugin interface with Vite-specific hooks.
|
||||
|
||||
## Basic Structure
|
||||
|
||||
```ts
|
||||
function myPlugin(): Plugin {
|
||||
return {
|
||||
name: 'my-plugin',
|
||||
// hooks...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Vite-Specific Hooks
|
||||
|
||||
### config
|
||||
|
||||
Modify config before resolution:
|
||||
|
||||
```ts
|
||||
const plugin = () => ({
|
||||
name: 'add-alias',
|
||||
config: () => ({
|
||||
resolve: {
|
||||
alias: { foo: 'bar' },
|
||||
},
|
||||
}),
|
||||
})
|
||||
```
|
||||
|
||||
### configResolved
|
||||
|
||||
Access final resolved config:
|
||||
|
||||
```ts
|
||||
const plugin = () => {
|
||||
let config: ResolvedConfig
|
||||
return {
|
||||
name: 'read-config',
|
||||
configResolved(resolvedConfig) {
|
||||
config = resolvedConfig
|
||||
},
|
||||
transform(code, id) {
|
||||
if (config.command === 'serve') { /* dev */ }
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### configureServer
|
||||
|
||||
Add custom middleware to dev server:
|
||||
|
||||
```ts
|
||||
const plugin = () => ({
|
||||
name: 'custom-middleware',
|
||||
configureServer(server) {
|
||||
server.middlewares.use((req, res, next) => {
|
||||
// handle request
|
||||
next()
|
||||
})
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Return function to run **after** internal middlewares:
|
||||
|
||||
```ts
|
||||
configureServer(server) {
|
||||
return () => {
|
||||
server.middlewares.use((req, res, next) => {
|
||||
// runs after Vite's middlewares
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### transformIndexHtml
|
||||
|
||||
Transform HTML entry files:
|
||||
|
||||
```ts
|
||||
const plugin = () => ({
|
||||
name: 'html-transform',
|
||||
transformIndexHtml(html) {
|
||||
return html.replace(/<title>(.*?)<\/title>/, '<title>New Title</title>')
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Inject tags:
|
||||
|
||||
```ts
|
||||
transformIndexHtml() {
|
||||
return [
|
||||
{ tag: 'script', attrs: { src: '/inject.js' }, injectTo: 'body' },
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### handleHotUpdate
|
||||
|
||||
Custom HMR handling:
|
||||
|
||||
```ts
|
||||
handleHotUpdate({ server, modules, timestamp }) {
|
||||
server.ws.send({ type: 'custom', event: 'special-update', data: {} })
|
||||
return [] // empty = skip default HMR
|
||||
}
|
||||
```
|
||||
|
||||
## Virtual Modules
|
||||
|
||||
Serve virtual content without files on disk:
|
||||
|
||||
```ts
|
||||
const plugin = () => {
|
||||
const virtualModuleId = 'virtual:my-module'
|
||||
const resolvedId = '\0' + virtualModuleId
|
||||
|
||||
return {
|
||||
name: 'virtual-module',
|
||||
resolveId(id) {
|
||||
if (id === virtualModuleId) return resolvedId
|
||||
},
|
||||
load(id) {
|
||||
if (id === resolvedId) {
|
||||
return `export const msg = "from virtual module"`
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Usage:
|
||||
|
||||
```ts
|
||||
import { msg } from 'virtual:my-module'
|
||||
```
|
||||
|
||||
Convention: prefix user-facing path with `virtual:`, prefix resolved id with `\0`.
|
||||
|
||||
## Plugin Ordering
|
||||
|
||||
Use `enforce` to control execution order:
|
||||
|
||||
```ts
|
||||
{
|
||||
name: 'pre-plugin',
|
||||
enforce: 'pre', // runs before core plugins
|
||||
}
|
||||
|
||||
{
|
||||
name: 'post-plugin',
|
||||
enforce: 'post', // runs after build plugins
|
||||
}
|
||||
```
|
||||
|
||||
Order: Alias → `enforce: 'pre'` → Core → User (no enforce) → Build → `enforce: 'post'` → Post-build
|
||||
|
||||
## Conditional Application
|
||||
|
||||
```ts
|
||||
{
|
||||
name: 'build-only',
|
||||
apply: 'build', // or 'serve'
|
||||
}
|
||||
|
||||
// Function form:
|
||||
{
|
||||
apply(config, { command }) {
|
||||
return command === 'build' && !config.build.ssr
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Universal Hooks (from Rolldown)
|
||||
|
||||
These work in both dev and build:
|
||||
|
||||
- `resolveId(id, importer)` - Resolve import paths
|
||||
- `load(id)` - Load module content
|
||||
- `transform(code, id)` - Transform module code
|
||||
|
||||
```ts
|
||||
transform(code, id) {
|
||||
if (id.endsWith('.custom')) {
|
||||
return { code: compile(code), map: null }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Client-Server Communication
|
||||
|
||||
Server to client:
|
||||
|
||||
```ts
|
||||
configureServer(server) {
|
||||
server.ws.send('my:event', { msg: 'hello' })
|
||||
}
|
||||
```
|
||||
|
||||
Client side:
|
||||
|
||||
```ts
|
||||
if (import.meta.hot) {
|
||||
import.meta.hot.on('my:event', (data) => {
|
||||
console.log(data.msg)
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
Client to server:
|
||||
|
||||
```ts
|
||||
// Client
|
||||
import.meta.hot.send('my:from-client', { msg: 'Hey!' })
|
||||
|
||||
// Server
|
||||
server.ws.on('my:from-client', (data, client) => {
|
||||
client.send('my:ack', { msg: 'Got it!' })
|
||||
})
|
||||
```
|
||||
|
||||
<!--
|
||||
Source references:
|
||||
- https://vite.dev/guide/api-plugin
|
||||
-->
|
||||
108
skills/vite/references/environment-api.md
Normal file
108
skills/vite/references/environment-api.md
Normal file
@@ -0,0 +1,108 @@
|
||||
---
|
||||
name: vite-environment-api
|
||||
description: Vite 6+ Environment API for multiple runtime environments
|
||||
---
|
||||
|
||||
# Environment API (Vite 6+)
|
||||
|
||||
The Environment API formalizes multiple runtime environments beyond the traditional client/SSR split.
|
||||
|
||||
## Concept
|
||||
|
||||
Before Vite 6: Two implicit environments (`client` and `ssr`).
|
||||
|
||||
Vite 6+: Configure as many environments as needed (browser, node server, edge server, etc.).
|
||||
|
||||
## Basic Configuration
|
||||
|
||||
For SPA/MPA, nothing changes—options apply to the implicit `client` environment:
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
build: { sourcemap: false },
|
||||
optimizeDeps: { include: ['lib'] },
|
||||
})
|
||||
```
|
||||
|
||||
## Multiple Environments
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
build: { sourcemap: false }, // Inherited by all environments
|
||||
optimizeDeps: { include: ['lib'] }, // Client only
|
||||
environments: {
|
||||
// SSR environment
|
||||
server: {},
|
||||
// Edge runtime environment
|
||||
edge: {
|
||||
resolve: { noExternal: true },
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Environments inherit top-level config. Some options (like `optimizeDeps`) only apply to `client` by default.
|
||||
|
||||
## Environment Options
|
||||
|
||||
```ts
|
||||
interface EnvironmentOptions {
|
||||
define?: Record<string, any>
|
||||
resolve?: EnvironmentResolveOptions
|
||||
optimizeDeps: DepOptimizationOptions
|
||||
consumer?: 'client' | 'server'
|
||||
dev: DevOptions
|
||||
build: BuildOptions
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Environment Instances
|
||||
|
||||
Runtime providers can define custom environments:
|
||||
|
||||
```ts
|
||||
import { customEnvironment } from 'vite-environment-provider'
|
||||
|
||||
export default defineConfig({
|
||||
environments: {
|
||||
ssr: customEnvironment({
|
||||
build: { outDir: '/dist/ssr' },
|
||||
}),
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
Example: Cloudflare's Vite plugin runs code in `workerd` runtime during development.
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
- `server.moduleGraph` returns mixed client/SSR view
|
||||
- `ssrLoadModule` still works
|
||||
- Existing SSR apps work unchanged
|
||||
|
||||
## When to Use
|
||||
|
||||
- **End users**: Usually don't need to configure—frameworks handle it
|
||||
- **Plugin authors**: Use for environment-aware transformations
|
||||
- **Framework authors**: Create custom environments for their runtime needs
|
||||
|
||||
## Plugin Environment Access
|
||||
|
||||
Plugins can access environment in hooks:
|
||||
|
||||
```ts
|
||||
{
|
||||
name: 'env-aware',
|
||||
transform(code, id, options) {
|
||||
if (options?.ssr) {
|
||||
// SSR-specific transform
|
||||
}
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
<!--
|
||||
Source references:
|
||||
- https://vite.dev/guide/api-environment
|
||||
- https://vite.dev/blog/announcing-vite6
|
||||
-->
|
||||
157
skills/vite/references/rolldown-migration.md
Normal file
157
skills/vite/references/rolldown-migration.md
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
name: vite-rolldown
|
||||
description: Vite 8 Rolldown bundler and Oxc transformer migration
|
||||
---
|
||||
|
||||
# Rolldown Migration (Vite 8)
|
||||
|
||||
Vite 8 replaces esbuild+Rollup with Rolldown, a unified Rust-based bundler.
|
||||
|
||||
## What Changed
|
||||
|
||||
| Before (Vite 7) | After (Vite 8) |
|
||||
|-----------------|----------------|
|
||||
| esbuild (dev transform) | Oxc Transformer |
|
||||
| esbuild (dep pre-bundling) | Rolldown |
|
||||
| Rollup (production build) | Rolldown |
|
||||
| `rollupOptions` | `rolldownOptions` |
|
||||
| `esbuild` option | `oxc` option |
|
||||
|
||||
## Performance Impact
|
||||
|
||||
- 10-30x faster than Rollup for production builds
|
||||
- Matches esbuild's dev performance
|
||||
- Unified behavior between dev and build
|
||||
|
||||
## Config Migration
|
||||
|
||||
### rollupOptions → rolldownOptions
|
||||
|
||||
```ts
|
||||
// Before (Vite 7)
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rollupOptions: {
|
||||
external: ['vue'],
|
||||
output: { globals: { vue: 'Vue' } },
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
// After (Vite 8)
|
||||
export default defineConfig({
|
||||
build: {
|
||||
rolldownOptions: {
|
||||
external: ['vue'],
|
||||
output: { globals: { vue: 'Vue' } },
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### esbuild → oxc
|
||||
|
||||
```ts
|
||||
// Before (Vite 7)
|
||||
export default defineConfig({
|
||||
esbuild: {
|
||||
jsxFactory: 'h',
|
||||
jsxFragment: 'Fragment',
|
||||
},
|
||||
})
|
||||
|
||||
// After (Vite 8)
|
||||
export default defineConfig({
|
||||
oxc: {
|
||||
jsx: {
|
||||
runtime: 'classic',
|
||||
pragma: 'h',
|
||||
pragmaFrag: 'Fragment',
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### JSX Configuration
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
oxc: {
|
||||
jsx: {
|
||||
runtime: 'automatic', // or 'classic'
|
||||
importSource: 'react', // for automatic runtime
|
||||
},
|
||||
jsxInject: `import React from 'react'`, // auto-inject
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Custom Transform Targets
|
||||
|
||||
```ts
|
||||
export default defineConfig({
|
||||
oxc: {
|
||||
include: ['**/*.ts', '**/*.tsx'],
|
||||
exclude: ['node_modules/**'],
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
## Plugin Compatibility
|
||||
|
||||
Most Vite plugins work unchanged. Rolldown supports Rollup's plugin API.
|
||||
|
||||
If a plugin only works during build:
|
||||
|
||||
```ts
|
||||
{
|
||||
...rollupPlugin(),
|
||||
enforce: 'post',
|
||||
apply: 'build',
|
||||
}
|
||||
```
|
||||
|
||||
## New Capabilities
|
||||
|
||||
Rolldown unlocks features not possible before:
|
||||
|
||||
- Full bundle mode (experimental)
|
||||
- Module-level persistent cache
|
||||
- More flexible chunk splitting
|
||||
- Module Federation support
|
||||
|
||||
## Gradual Migration
|
||||
|
||||
For large projects, migrate via `rolldown-vite` first:
|
||||
|
||||
```bash
|
||||
# Step 1: Test with rolldown-vite
|
||||
pnpm add -D rolldown-vite
|
||||
|
||||
# Replace vite import in config
|
||||
import { defineConfig } from 'rolldown-vite'
|
||||
|
||||
# Step 2: Once stable, upgrade to Vite 8
|
||||
pnpm add -D vite@8
|
||||
```
|
||||
|
||||
## Overriding Vite in Frameworks
|
||||
|
||||
When framework depends on older Vite:
|
||||
|
||||
```json
|
||||
{
|
||||
"pnpm": {
|
||||
"overrides": {
|
||||
"vite": "8.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<!--
|
||||
Source references:
|
||||
- https://vite.dev/blog/announcing-vite8-beta
|
||||
- https://vite.dev/blog/announcing-vite7
|
||||
- https://vite.dev/config/shared-options#oxc
|
||||
-->
|
||||
Reference in New Issue
Block a user