Weevarv2.0

Vite plugin

Source-accurate prompts and Tailwind detection for Vite-based React apps.

What it does#

Three things:

  1. Injects data-wv-source="<file>:<line>:<col>" onto every JSX element in your project at dev-build time. The runtime reads this attribute to anchor prompts to source code.
  2. Probes for Tailwind. If it finds tailwind.config.{js,ts,mjs,cjs} or the tailwindcss package, it auto-enables tailwindVerbatimClasses for the prompt generator.
  3. Exposes a virtual module virtual:weevar-config that returns your merged config (weevar.config.json + weevar.config.js/mjs + Tailwind probe results), so the runtime can pick it up without a separate file read.

The plugin runs in the pre phase, before @vitejs/plugin-react, so the JSX it transforms is the source you wrote, not React's output.


Install#

The plugin is bundled with the main package - no separate install.

npm install weevar

Register#

// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { weevar } from "weevar/vite";

export default defineConfig({
  plugins: [weevar(), react()],
});

Order matters. weevar() should come before react() so it sees the JSX before the React plugin transforms it.


What gets injected#

For every JSX opening tag (.jsx, .tsx) outside node_modules, the plugin appends an attribute like:

<NavItem data-wv-source="src/components/NavItem.tsx:12:4" />

The value is the path relative to your project root, plus the line and column where the tag begins. If a data-wv-source is already present (because you set it manually, or another plugin did), the existing one is kept.


Tailwind detection#

On startup, the plugin walks up from your project's cwd looking for:

  • tailwind.config.js / .ts / .mjs / .cjs
  • tailwindcss listed in package.json dependencies / devDependencies
  • content globs declared in your tailwind config

If any of those match, the merged config returned by the virtual module gets:

{
  prompts: {
    tailwindVerbatimClasses: true,
    tailwindContentGlobs: [...],     // when content globs are resolvable
    tailwindConfigPath: "tailwind.config.ts",
  }
}

You don't need to set anything manually. When this is active, layout prompts include verbatim class strings, and style tweak prompts include Tailwind utility suggestions alongside the raw CSS values.


Virtual config module#

The plugin resolves virtual:weevar-config (with a leading null byte internally) to a small ES module that exports your merged config as the default. The runtime imports this lazily.

If you want to read it from your own code:

import config from "virtual:weevar-config";
console.log(config.prompts);

It's a frozen JSON value; no functions are evaluated at runtime.


Config precedence#

When the plugin builds the merged config, the order is:

  1. Default values (none - empty object)
  2. weevar.config.json if it exists
  3. weevar.config.mjs or weevar.config.js if it exists (JS wins on overlap; deep-merged)
  4. Tailwind probe results (only set if not already specified)
  5. Inline <Weevar config={...} /> props (deep-merged at runtime)

See Config file → for the schema.


Opting out of source injection#

The plugin currently has no opt-out flag for source injection. If you need it skipped for a specific file, set data-wv-source manually on the relevant elements (it won't be overwritten) or move the file to a path the plugin doesn't match (e.g. node_modules).