Repository navigation
devtools-vite: four transform hooks have no filter, and inject-plugin parses pre-bundled dependency chunks #553
Description
TanStack Devtools version
@tanstack/devtools-vite 0.8.5 (its src/plugin.ts is the same as main at 6fbe63f)
Framework/Library version
Vite 8.0.12 and 8.3.4, React 19.2
Describe the bug and the steps to reproduce it
A dev server calls a transform hook on every module unless the hook declares a filter. In packages/devtools-vite/src/plugin.ts, four hooks declare none: remove-devtools-on-build, inject-plugin, connection-injection and runtime-bridge. Their handlers return early for almost every module, but only after Vite has called them. inject-plugin first parses the module with oxc (detectDevtoolsFile), and keeps doing so until it finds the file that imports a devtools package. Nothing keeps it out of node_modules, so it also parses Vite's pre-bundled dependency chunks, which are large and which a page loads early.
inject-source has a filter, but it still parses every .ts file, though these cannot contain JSX, and every file with no < in it.
To reproduce:
- Clone the gist, run
npm install, thennpm run check. - The script lists the hooks without a filter. It then calls each hook the way Vite would: on 271 TypeScript and TSX files (the sources that the installed
@tanstackpackages ship, standing in for an app's own files) and on the 953 files innode_modules. It prints the calls, the modules each hook changed, and the time.
Output on an Apple M6 with Node 24.21:
Transform hooks without a filter: remove-devtools-on-build, inject-plugin, connection-injection, runtime-bridge
App modules (sample-app): 271 modules
hook filter calls changed ms
inject-source yes 271 53 81.1
remove-devtools-on-build no 271 1 13.1
better-console-logs yes 32 11 19.9
console-pipe-transform yes 268 10 2.0
inject-plugin no 271 1 33.8
connection-injection no 271 0 0.3
runtime-bridge no 271 0 0.1
total 150.2
Dependency modules (node_modules): 953 modules
hook filter calls changed ms
inject-source yes 0 0 0.0
remove-devtools-on-build no 953 0 0.1
better-console-logs yes 0 0 0.0
console-pipe-transform yes 0 0 0.0
inject-plugin no 953 1 49.9
connection-injection no 953 2 4.2
runtime-bridge no 953 0 0.1
total 54.3
The same on a dev server, timing each handler during the first page load (median of 10 cold starts):
examples/react/start, 321 modules across the client, SSR and Nitro environments: the plugin's handlers take 54 ms, andinject-plugintakes 39 ms of that. It is called on all 321 modules.- shadcn-admin (at e16c87f) with
devtools()and<TanStackDevtools />added as the docs describe, 176 client modules: the handlers take 93 ms, andinject-plugintakes 73 ms. It parses the pre-bundled chunks before it reachessrc/routes/__root.tsx, the 27th module. The 802 KBreact-domclient chunk alone takes 48 ms.
The cost grows with the number of modules. In a Vite 8 build, Rolldown must call a JavaScript hook without a filter for every module; #394 reports remove-devtools-on-build at 46% of plugin time in a build.
Expected: each hook declares a filter that matches the checks its handler already makes, so Vite and Rolldown skip the modules it would ignore.
Related: #397 (for #398) made each parse cheaper; this is about how many modules get parsed.
Your Minimal, Reproducible Example - (Sandbox Highly Recommended)
https://gist.github.com/shkumbinhasani/1f68aa6ded48473e3519964a1e0d903a
Screenshots or Videos (Optional)
No response
Do you intend to try to help solve this bug with your own PR?
Yes, I am also opening a PR that solves the problem along side this issue
Terms & Code of Conduct
- I agree to follow this project's Code of Conduct
- I understand that if my bug cannot be reliable reproduced in a debuggable environment, it will probably not be fixed and this issue may even be closed.
Activity