Files
Yunfei He 0a774ddc8c refactor(vite)!: make @vue-tui/vite dev-only; build apps with tsdown (#247)
`vite build` is a browser-first bundler, so producing a runnable Node program
from it meant constantly overriding its defaults (platform, externalization,
inlineDynamicImports, module-preload). Building a Node app is a Node bundler's
job — so split vue-tui's two jobs across two tools:

- @vue-tui/vite is now DEV-ONLY (in-terminal dev server + HMR). Removed
  buildConfigPlugin and the externalize predicate: deleted src/build.ts,
  src/external.ts (+ external.spec.ts) and test/build.sequential.test.ts.
  vueTui() returns just the dev + dev-vmod plugins, and entry normalization is
  dev-only; dev.spec.ts updated.
- Production builds move to tsdown + unplugin-vue: a plain tsdown.config.ts that
  bundles the whole app into one self-contained Node file (dist/*.mjs) runnable
  with no node_modules. platform:node keeps builtins external and emits a real
  createRequire for CJS deps; deps.alwaysBundle inlines everything else.
- Migrated all five examples to tsdown (including flappy-bird, which hand-rolled
  a vite lib-mode self-contained build), and rewrote the examples smoke suite to
  build via tsdown and launch each self-contained bundle from an empty sandbox.
- Added tsdown + unplugin-vue-jsx to the catalog; updated the root and
  @vue-tui/vite READMEs.

BREAKING CHANGE: @vue-tui/vite no longer configures `vite build`. Build the app
with tsdown instead (see the @vue-tui/vite README, examples/*, and the starter).
2026-07-06 00:29:28 +08:00
..

@vue-tui/vite

Vite plugin for vue-tui: an in-process terminal dev server with HMR, for Vue apps that render to the terminal via @vue-tui/runtime.

Install

npm install -D @vue-tui/vite @vitejs/plugin-vue
# peer deps: vite ^8, @vue-tui/runtime

Usage

vueTui() adds the terminal dev server (HMR). Bring your own SFC/JSX compiler alongside it — @vitejs/plugin-vue for SFCs (or @vitejs/plugin-vue-jsx for JSX):

// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { vueTui } from "@vue-tui/vite";

export default defineConfig({
  plugins: [vue(), vueTui()],
});
  • vite (dev) — boots the app in-process through Vite's SSR module runner and renders it to the terminal, with state-preserving HMR.

Options

vueTui({
  entry: "src/main.ts", // default; the app entry (a .ts/.tsx file, not an index.html)
});

For a JSX/TSX entry, use @vitejs/plugin-vue-jsx and point entry at the .tsx file:

import vueJsx from "@vitejs/plugin-vue-jsx";

export default defineConfig({
  plugins: [vueJsx(), vueTui({ entry: "/src/main.tsx" })],
});

Production build

vueTui() is dev only — it does not touch the production build. vite build is browser-first and the wrong tool for a Node program, so build with tsdown instead: it bundles the whole app into one self-contained Node file that runs with no node_modules present.

// tsdown.config.ts
import { defineConfig } from "tsdown";
import Vue from "unplugin-vue/rolldown"; // or unplugin-vue-jsx/rolldown for a .tsx entry

export default defineConfig({
  entry: ["src/main.ts"],
  platform: "node", // keep Node builtins external; real createRequire for CJS deps
  format: "esm",
  deps: { alwaysBundle: [/./], onlyBundle: false }, // inline every dep into the one file
  plugins: [Vue()],
});
npm install -D tsdown unplugin-vue
tsdown # → dist/main.mjs, self-contained

See the starter and this repo's examples/ for complete setups.

License

MIT