Commit 6039884
feat(plugin): twd() Vite plugin for plug-and-play dev setup (#238)
* docs: add design spec for TWD Vite plugin auto-init POC
Captures the design for moving the dev-only initTWD(...) block out of
user entry files into a single Vite plugin call. POC scope, validation
criteria, backward-compat plan, and deferred follow-ups documented.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(plugin): scaffold twd Vite plugin (name + apply: serve)
Initial plugin shell with name 'twd' and apply: 'serve' so it only
runs at dev time. Hooks added in subsequent tasks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(plugin): add virtual module for twd init
resolveId / load hooks emit a virtual:twd/init module containing
import { initTWD } + import.meta.glob + initTWD call with default
options inlined via JSON.stringify.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* test(plugin): cover custom options + testFilePattern round-trip
Locks the contract that custom init options are JSON-serialized into
the virtual module and that testFilePattern is consumed by the plugin
without leaking into initTWD's options object.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(plugin): inject virtual init script via transformIndexHtml
Adds a <script type="module" src="/@id/virtual:twd/init"> tag to the
served HTML so the virtual module executes in the browser at dev time.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(plugin): export twd from twd-js/vite-plugin
Adds twd() and TwdPluginOptions to the public vite-plugin entry
alongside the existing twdHmr and removeMockServiceWorker exports.
Includes JSDoc + @example matching the twdHmr documentation style.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(examples): switch twd-test-app to twd() Vite plugin
Removes the entry-file initTests/initRequestMocking block; the new
twd() Vite plugin handles both via the injected virtual init module.
The twd-relay browser-client init stays in main.tsx (separate concern).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(examples): alias twd-js/bundled to dist (not source) in test app
The previous alias pointed to src/bundled.tsx, exposing the source
file to the test app's React JSX transform. The resulting React
vnodes are frozen by React.createElement in dev, so Preact's
render() crashed trying to attach __ properties.
Switching the alias to dist/bundled.es.js uses the artifact built
with @preact/preset-vite (Preact JSX baked in), eliminating the
mismatch.
Documents the same caveat in the design spec: in-repo / local-dist
consumers must alias to the built file, not source.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(examples): adopt twd() plugin in tutorial and vue examples
tutorial-example: drop the dev-only initTWD block from main.tsx and
register twd() in vite.config.ts; alias twd-js/bundled to the local
src/dist copy since the tutorial does not install twd-js as a package.
vue-twd-example: same migration, plus relocate the dark theme literal
into vite.config.ts so initTWD options live in one place. main.ts is
now a 5-line Vue bootstrap.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: switch tsconfig moduleResolution to Bundler
Vite 8 ships its types only through conditional package.json exports,
which the legacy 'Node' moduleResolution cannot read. The result was
TS2307 errors on every 'import type { Plugin } from "vite"' across
the existing twdHmr / removeMockServiceWorker plugins (and the new
twd plugin inherited the same issue).
'Bundler' is the recommended setting for Vite-based projects and is
already consistent with the existing module: ESNext / target: ESNext.
402/402 tests pass and npm run build succeeds after the change.
The remaining tsc --noEmit complaints (fs/path in
removeMockServiceWorker.ts, two unrelated url.spec.ts findings) are
pre-existing and out of scope for this branch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(deps): bump lint-staged to 17 and typescript-eslint patch
The typescript-eslint 8.59.2 patch tightens no-floating-promises and
flagged two pre-existing call sites in twdHmr.spec.ts where the
handleHotUpdate hook (typed as void | Promise<void>) was invoked
without awaiting. Prefix the calls with the void operator so the
fire-and-forget intent is explicit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: add better tests for pagination example
* chore(release): 1.8.0-beta.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs: lead with twd() Vite plugin across docs site and README
Migrates the docs to recommend the new twd() Vite plugin as the
primary setup for Vite-based projects (React, Vue, Solid.js, Astro).
The manual initTWD bundled approach is now positioned as the
fallback for non-Vite projects (Angular, Webpack/CRA) and as a
secondary option for Vite users who need full control.
Pages updated:
- README.md — installation snippet
- docs/.vitepress/theme/components/HomePage.vue — quick start
- docs/getting-started.md — primary setup + manual non-Vite section
- docs/tutorial/installation.md — tutorial first install step
- docs/frameworks.md — React/Vue/Solid lead with plugin; Angular and CRA stay manual; Astro updated to use plugin via vite block
- docs/theming.md — theme passed via plugin in vite.config.ts
- docs/api/index.md — twd() plugin documented first; initTWD as manual API
- docs/testing-library.md — rootSelector example shows both plugin and manual
- docs/api-mocking.md — service worker registration via plugin (default)
- docs/tutorial/api-mocking.md — same pattern in tutorial flavor
- docs/coverage.md + tutorial/coverage.md — twd() plus istanbul example
- docs/tutorial/production-builds.md — removeMockServiceWorker import path corrected
- docs/claude-plugin.md — auto-setup uses plugin
- docs/ai-remote-testing.md — twd() and twdRemote() shown together
npx twd-js init public is still mentioned in getting-started and
api-mocking — auto-install hasn't shipped yet.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(release): 1.8.0
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(plugin): add @example for serviceWorker option in twd() JSDoc
Surfaces the request-mocking toggles (serviceWorker, serviceWorkerUrl)
in the function-level JSDoc so they're discoverable via IntelliSense
without expanding the options interface. Caught during real-project
migration where a reviewer concluded the options had been dropped
because they weren't shown in the function's example block.
No runtime change — JSDoc only.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(plugin): respect Vite base path in script injection and SW URL
The plugin was emitting a hardcoded "/@id/virtual:twd/init" script
tag in transformIndexHtml(), which 404s on dev servers configured
with a non-root base (e.g. base: "/platform-admin/") because Vite
serves all dev resources under that prefix.
Capture the resolved base via configResolved() and prefix:
- script src in transformIndexHtml — always
- default serviceWorkerUrl — only when the user did NOT explicitly
set it (so user-supplied paths like "/platform-admin/mock-sw.js"
are not double-prefixed)
Default base "/" preserves existing behavior. Tests cover all four
combinations (base x serviceWorkerUrl override).
Reported by a real-project consumer with:
base: "/platform-admin/"
→ GET http://localhost:5173/@id/virtual:twd/init 404
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(release): 1.8.0-beta.1
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent d22b144 commit 6039884
38 files changed
Lines changed: 1460 additions & 676 deletions
File tree
- docs
- .vitepress/theme/components
- api
- tutorial
- examples
- tutorial-example
- public
- src
- twd-test-app
- public
- src
- loaders
- pages
- twd-tests
- vue-twd-example
- public
- src
- specs
- src
- constants
- plugin
- tests/plugin
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
1 | 22 | | |
2 | 23 | | |
3 | 24 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
36 | 36 | | |
37 | 37 | | |
38 | 38 | | |
39 | | - | |
| 39 | + | |
40 | 40 | | |
41 | | - | |
| 41 | + | |
42 | 42 | | |
43 | 43 | | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
58 | 59 | | |
59 | 60 | | |
60 | 61 | | |
| |||
65 | 66 | | |
66 | 67 | | |
67 | 68 | | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
68 | 88 | | |
69 | 89 | | |
70 | 90 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
249 | 249 | | |
250 | 250 | | |
251 | 251 | | |
252 | | - | |
| 252 | + | |
253 | 253 | | |
254 | 254 | | |
255 | 255 | | |
256 | 256 | | |
257 | 257 | | |
258 | | - | |
259 | | - | |
260 | | - | |
261 | | - | |
262 | | - | |
263 | | - | |
264 | | - | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
265 | 265 | | |
266 | 266 | | |
267 | 267 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
56 | 56 | | |
57 | 57 | | |
58 | 58 | | |
59 | | - | |
| 59 | + | |
60 | 60 | | |
61 | 61 | | |
62 | 62 | | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
63 | 66 | | |
64 | 67 | | |
65 | 68 | | |
66 | 69 | | |
67 | 70 | | |
68 | | - | |
| 71 | + | |
| 72 | + | |
69 | 73 | | |
70 | 74 | | |
71 | 75 | | |
| |||
76 | 80 | | |
77 | 81 | | |
78 | 82 | | |
79 | | - | |
80 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
81 | 87 | | |
82 | 88 | | |
83 | 89 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | | - | |
| 33 | + | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | | - | |
39 | | - | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
40 | 40 | | |
41 | 41 | | |
42 | 42 | | |
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | | - | |
| 51 | + | |
52 | 52 | | |
53 | 53 | | |
54 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
55 | 81 | | |
56 | | - | |
| 82 | + | |
57 | 83 | | |
58 | 84 | | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
65 | | - | |
| 85 | + | |
66 | 86 | | |
67 | 87 | | |
68 | 88 | | |
69 | 89 | | |
70 | | - | |
| 90 | + | |
71 | 91 | | |
72 | 92 | | |
73 | 93 | | |
| |||
0 commit comments