Describe the bug
When a Storybook project includes .mdx story files, the Vite dev server throws:
Vite Internal server error: Failed to resolve import
"file:///path/to/node_modules/@storybook/addon-docs/dist/mdx-react-shim.js"
from "SomeFile.mdx". Does the file exist?
Plugin: vite:import-analysis
The MDX compiler emits an import using a file:// URL as the specifier:
import { useMDXComponents as _provideComponents } from
"file:///absolute/path/to/node_modules/@storybook/addon-docs/dist/mdx-react-shim.js";
Vite's vite:import-analysis plugin cannot resolve file:// URL import specifiers, so the build fails.
Root cause
In addon-docs/dist/preset.js and addon-docs/dist/_node-chunks/mdx-plugin-5AO2VUFZ.js, providerImportSource is set using a raw import.meta.resolve() call:
// ✗ raw file:// URL — Vite cannot resolve this as an import specifier
providerImportSource: import.meta.resolve("@storybook/addon-docs/mdx-react-shim"),
import.meta.resolve() in Node.js ESM always returns a file:// URL. This is used verbatim by the MDX compiler as the import source in the compiled output.
Notably, @mdx-js/react is handled correctly in the same file:
// ✓ fileURLToPath converts file:// → absolute path, added as a Vite alias
mdx: resolvedReact2.mdx ?? fileURLToPath(import.meta.resolve("@mdx-js/react"))
The fix for mdx (fileURLToPath + alias) was applied but the same treatment was never applied to providerImportSource.
To reproduce
- Create a Storybook project with @storybook/react-vite, can be done in an empty dir
- Downgrade to Vite 5
- Start Storybook — the error appears immediately
Expected behavior
The MDX compiler should receive either a package specifier (@storybook/addon-docs/mdx-react-shim) or a plain absolute path, not a file:// URL.
Suggested fix
In src/preset.ts (and the Vite MDX plugin), wrap the import.meta.resolve() call with fileURLToPath, and add @storybook/addon-docs/mdx-react-shim to the Vite alias map — exactly as is already done for @mdx-js/react:
+ import { fileURLToPath } from 'node:url';
mdxCompileOptions: {
- providerImportSource: import.meta.resolve("@storybook/addon-docs/mdx-react-shim"),
+ providerImportSource: fileURLToPath(import.meta.resolve("@storybook/addon-docs/mdx-react-shim")),
}
Workaround
For anyone facing the issue, add a viteFinal to .storybook/main.ts that strips the file:// protocol from import specifiers before Vite's import analysis runs:
viteFinal: async (config) => ({
...config,
plugins: [
...(config.plugins || []),
{
name: "resolve-file-urls",
resolveId(id: string) {
if (id.startsWith("file://")) return id.replace("file://", "");
},
},
],
}),
Reproduction link
Reproduction steps
No response
System
Additional context
No response
Describe the bug
When a Storybook project includes .mdx story files, the Vite dev server throws:
Root cause
In
addon-docs/dist/preset.jsandaddon-docs/dist/_node-chunks/mdx-plugin-5AO2VUFZ.js,providerImportSourceis set using a rawimport.meta.resolve()call:import.meta.resolve()in Node.js ESM always returns afile://URL. This is used verbatim by the MDX compiler as the import source in the compiled output.Notably,
@mdx-js/reactis handled correctly in the same file:The fix for mdx (fileURLToPath + alias) was applied but the same treatment was never applied to providerImportSource.
To reproduce
Expected behavior
The MDX compiler should receive either a package specifier (@storybook/addon-docs/mdx-react-shim) or a plain absolute path, not a file:// URL.
Suggested fix
In
src/preset.ts(and the Vite MDX plugin), wrap theimport.meta.resolve()call withfileURLToPath, and add@storybook/addon-docs/mdx-react-shimto the Vite alias map — exactly as is already done for@mdx-js/react:Workaround
For anyone facing the issue, add a viteFinal to
.storybook/main.tsthat strips thefile://protocol from import specifiers before Vite's import analysis runs:Reproduction link
Reproduction steps
No response
System
Additional context
No response