vite-plugin-cooked
v1.0.1
Published
Vite's ?raw gives you uncooked source. This gives you the cooked version — compiled, bundled, and tree-shaken.
Maintainers
Readme
Why
// ?raw → uncooked: types, JSX, and imports stay as-is. Can't run in a browser.
import raw from './worker.ts?raw'
// ?to=js → cooked: compiled to JS, all deps bundled in, tree-shaken. Ready to execute.
import cooked from './worker.ts?to=js'Install
npm install -D vite-plugin-cookedSetup
// vite.config.ts
import { defineConfig } from 'vite'
import cooked from 'vite-plugin-cooked'
export default defineConfig({
plugins: [cooked()],
})Usage
import code from './worker.ts?to=js' // bundle + compile to JS
import min from './worker.ts?minify&to=js' // + minify
import iife from './worker.ts?format=iife&minify&to=js' // IIFE for Workers / <script>
import lite from './widget.tsx?external=react,react-dom&to=js' // keep react as import
import all from './lib.ts?external=*&to=js' // keep all bare imports
import raw from './utils.ts?nobundle&to=js' // single-file transpile onlyTypeScript tip: Put
to=js/to=tslast in the query. The type declarations use*to=jspatterns —?minify&to=jsmatches,?to=js&minifydoes not.
Query Parameters
| Param | Values | Description |
|-------|--------|-------------|
| to | js, ts | Target format. js strips types and compiles JSX. |
| minify | flag | Minify the output. |
| target | e.g. es2020 | Syntax downleveling target. |
| banner | string | Text prepended to output (URL-encode special chars). |
| format | es, iife | Output format. Default es. iife for Workers / scripts. |
| external | pkg names or * | Deps to exclude from bundle, comma-separated. * = all bare imports. |
| nobundle | flag | Skip bundling — transpile only, imports preserved. |
Options
cooked({
defaultTarget: 'es2020',
defaultMinify: false,
defaultFormat: 'es',
defaultExternal: ['react', 'react-dom'],
})TypeScript
{
"compilerOptions": {
"types": ["vite-plugin-cooked/client"]
}
}Bundle vs Nobundle
| | Bundle (default) | Nobundle (&nobundle) |
|---|---|---|
| Imports | Resolved, inlined, tree-shaken | Preserved as-is |
| Output | Self-contained | Single-file transpile |
| Speed | Slower (full build) | Fast |
FAQ
How is this different from ?worker?
?worker returns a Worker constructor from a separate file. cooked returns a code string — you control where it runs: Worker, iframe, <script>, sandbox.
Isn't ?raw enough?
?raw returns uncompiled source. TypeScript types, JSX, and bare imports can't execute in a browser. cooked compiles and bundles first.
Can I cook .vue / .svelte files?
Not yet. The internal build uses configFile: false and doesn't load framework plugins.
Limitations
- Dep changes don't trigger HMR — only the entry file is watched. Re-save entry or restart dev server.
- CSS imports are ignored — cooked outputs a string, CSS has nowhere to inject. A warning is logged.
- No source maps — output is a string constant. Use
&nobundlefor easier debugging. - Dynamic imports break — no separate chunks exist after bundling. Use static imports only.
import.meta.urlchanges — points to blob/injection URL, not the original file.?to=tsrequires&nobundle— bundle mode always compiles to JS.&external=*+&format=iife— not supported. IIFE needs explicit globals mapping.- Build perf — each cooked import runs a full
vite.build(). Results are cached and concurrency is capped at 3.
Compatibility
| Vite | Behavior |
|------|----------|
| 4 – 7 | transformWithEsbuild for nobundle transforms |
| 8+ | transformWithOxc when available, esbuild fallback for minification |
