vitepress
vitepress copied to clipboard
Site config and data loaders don't support subpath imports
Describe the bug
Subpath imports configured in package.json are not resolved in .vitepress/config.ts and *.data.ts.
Reproduction
- Configure subpath imports in
package.json
"imports": {
"#*": "./*"
}
- Create a module exporting data in the project root
// sharedData.ts
export default {
siteTitle: 'Shared site title',
};
- Import the module
in .vitepress/config.ts
import { defineConfig } from 'vitepress';
import sharedData from '#sharedData';
export default defineConfig({
title: sharedData.siteTitle,
});
in a data loader
import { defineLoader } from 'vitepress';
import sharedData from '#sharedData';
export default defineLoader({
watch: ['./sharedData.ts'],
load: () => sharedData,
});
Expected behavior
import sharedData from '#sharedData'
should work identically to
import sharedData from '../../sharedData'
and set the site title to Shared site title.
System Info
System:
OS: Linux 5.0 undefined
CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 0 Bytes / 0 Bytes
Shell: 1.0 - /bin/jsh
Binaries:
Node: 18.20.3 - /usr/local/bin/node
Yarn: 1.22.19 - /usr/local/bin/yarn
npm: 10.2.3 - /usr/local/bin/npm
pnpm: 8.15.6 - /usr/local/bin/pnpm
npmPackages:
vitepress: latest => 1.3.4
Additional context
Running VitePress with Bun (bun --bun run docs:dev) or tsx tsx node_modules/vitepress/bin/vitepress.js works around the issue.
Validations
- [X] Check if you're on the latest VitePress version.
- [X] Follow our Code of Conduct
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
I don't think node supports that. You'll need to change it to "#*": "./*.js" and use js for it to work.
esbuild doesn't transform that while importing. So, it's whatever node supports. Intermediate code:
bun and tsx have very lax resolution algorithms and support extension-less imports in ESM and TS.
I tried the following configurations:
import sharedData from '#sharedData.js'with imports set to"#*": "./*.js":
Cannot find module '/home/projects/vitepress-subpath-imports/sharedData.js.js'
import sharedData from '#sharedData'with imports set to"#*": "./*":
Cannot find module '/home/projects/vitepress-subpath-imports/sharedData.js'
import sharedData from '#sharedData.js'with imports set to"#*": "./*":
Cannot find module '/home/projects/vitepress-subpath-imports/sharedData.js'
Unfortunately none of the configuration worked.
esbuild doesn't transform that while importing.
It's interesting that the second configuration throws an error with sharedData.js, even when no extensions are specified. Why does this happen?
I meant try this:
import sharedData from '#sharedData'
"#*": "./*.js"
// sharedData.js
export stuff ...
It's not specific to vitepress. Create a normal foo.js file and add the import there and run it with node foo.js.
https://stackblitz.com/edit/node-u1evg5?file=index.js
Thank you for pointing that out! I hadn't tried that specific configuration before.
While your solution works perfectly for JavaScript files, I noticed that it doesn't seem to work for TypeScript files. Do you have any suggestions on how to make this work with TypeScript as well?
Edit: "#*": "./*" also works for JavaScript files.
Do you have any suggestions on how to make this work with TypeScript as well?
Ah, currently no. You'll need to use tsx, or switch completely to bun. Newer node versions have added an experimental strip types flag that might also work in certain cases. But even then updates in that subpath imported file won't be tracked and config won't auto-reload. You'll need to manually restart your server every time you change that file.