iTranslated by AI
Building a VS Code extension to preview the current file with Vite
A "made it because I wanted it" series.
I think the images will convey what it is.

I'm using it myself, and while there are some limitations, it's quite comfortable.

What is this
A VSCode extension that builds the currently open file with Vite and previews it as a Webview Panel within VSCode.
// Component with the same name as the file and no props
export default function Sub() {
return <h1 className="flex">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Click mee
</button>
</h1>
}
Or, if a __PREVIEW__ component is exported, it uses that.
// Component with the same name as the file and no props
export default function Sub(props: {name: string}) {
return <h1 className="flex">
<button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Click {props.name}
</button>
</h1>
}
// This part gets rendered
export const __PREVIEW__ = () => {
return <Sub name="dummy" />
}
It also supports .svelte and .html. The supported patterns are as follows:
Note that previews will fail when dynamic imports are involved.
Sample project with React + Tailwind:
One benefit of using a webview panel is that since VSCode is built on Electron, it actually includes the same DevTools as Chrome. You can open them via Developer: Toggle Developer Tools and inspect elements within VSCode.

The debugger can also be used as is.
A similar HTML preview tool is https://marketplace.visualstudio.com/items?itemName=antfu.browse-lite, but it works by running Puppeteer internally and just transferring images, so the resolution ends up being blurry. vscode-vite also suffers from the same issue.
Since this extension runs in a webview panel, there are no resolution issues, but there is a possibility of being affected by CSS automatically injected by VSCode.
Installation
I haven't uploaded it to the VSCode Marketplace yet, so it's assumed to be installed from the binary (vsix).
$ wget https://github.com/mizchi/vscode-vite-preview/raw/main/extensions/vite-preview/releases/vite-preview-0.0.1.vsix
## Install to VSCode via CLI
$ code --install-extension vite-preview-0.0.1.vsix
This makes the VSCode command Vite Preview: Preview Current (default: ctrl-alt+r) available. This builds the currently open file with Vite and displays it as a webview within VSCode.
However, the Vite configuration for that project must be set up.
Create project
$ pnpm create vite@latest myapp
$ cd myapp
$ pnpm install
## Optional
$ pnpm add tailwindcss postcss autoprefixer -D
$ pnpm tailwind init
Optional: postcss and tailwind
Update the file references in tailwind.config.js and postcss.config.js to use absolute paths. (TODO: I want to fix this...)
const path = require("path");
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
path.join(__dirname, "src/**/*.{html,ts,tsx,svelte}"),
],
theme: {
extend: {},
},
plugins: [],
}
const path = require("path");
module.exports = {
plugins: {
autoprefixer: {},
tailwindcss: {
config: path.join(__dirname, "tailwind.config.js"),
},
}
}
Optional: preview.html
If you place preview.html in the same directory as vite.config.ts, it will be used as the entry point for the preview.
Example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body.vscode-light,
body.vscode-dark {
color: black;
background-color: white;
}
#preview-root {
padding: 10px;
box-sizing: border-box;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="preview-root"></div>
<script type="module" src="/src/pre.ts"></script>
<script type="module" src="/__PREVIEW__.tsx"></script>
</body>
</html>
This VSCode extension automatically infers the context of the currently open file and generates the contents of /__PREVIEW__.tsx.
How it works
It uses a dedicated plugin based on https://github.com/richardtallent/vite-plugin-singlefile to output a single HTML file that mounts the currently open file, which is then embedded and opened as the HTML of a VSCode webview.
One challenge I faced while building this was that when trying to run Vite with VSCode extension permissions, I encountered the issue where dynamic imports cannot be used within vm.Script, something that sosukesuzuki also struggled with.
So, by running Vite inside worker_threads like vscode-prettier does, I managed to get it working.
Future
I want to use it more myself, find truly necessary patterns, and then publish it to the VSCode Marketplace.
Currently, there are so many prerequisites that it feels like you can't use it without reading the code. For example, some parts must be absolute paths due to PostCSS execution paths, and dynamic imports don't work...
In truth, rather than being a standalone tool, I was creating this to preview code generated by ChatGPT, so I think it will serve as a component for that purpose.
Discussion