Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/devtools-optional-peer-stub.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@solidjs/vite-plugin': patch
---

Start devtools are no longer enabled when `@solidjs/start-devtools` is not installed. Detection falls back to resolving the package from the plugin's own file (for pnpm-isolated installs where it is only a dependency of the plugin), but the package is declared an optional peer dependency of the plugin, so when it is absent Vite answers that resolution with its `__vite-optional-peer-dep:` stub instead of `null`. The plugin took the stub as a successful resolution, wrapped the generated client entry in `DevToolbar`, and the browser failed with `The requested module '/@id/__vite-optional-peer-dep:@solidjs/start-devtools:@solidjs/vite-plugin' does not provide an export named 'DevToolbar'`. The stub is now treated as "not installed".
17 changes: 12 additions & 5 deletions src/ssr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,11 +489,18 @@ export function startServe(
// from the plugin's own file: in pnpm-isolated apps a copy that is only a
// dependency of the plugin is not reachable from the app's importers. The
// resolved id is kept so imports from generated modules can use it.
devtoolsResolutions[consumer] ??= (async () =>
(
(await resolve(DEVTOOLS_PACKAGE, importer)) ??
(await resolve(DEVTOOLS_PACKAGE, fileURLToPath(import.meta.url)))
)?.id ?? null)();
devtoolsResolutions[consumer] ??= (async () => {
// Resolving from the plugin's own file never yields null when the
// package is absent: it is declared an optional peer dependency, so
// Vite answers with its `__vite-optional-peer-dep:` stub (an empty
// module). Treat that stub as "not installed".
const realId = (resolved: { id: string } | null) =>
resolved && !resolved.id.startsWith('__vite-optional-peer-dep:') ? resolved.id : null;
return (
realId(await resolve(DEVTOOLS_PACKAGE, importer)) ??
realId(await resolve(DEVTOOLS_PACKAGE, fileURLToPath(import.meta.url)))
);
})();
const id = await devtoolsResolutions[consumer];
devtoolsIds[consumer] = id;
if (!id && options.devtools === true) {
Expand Down
Loading