The problem occurs for Vite monorepo, @
aliases are respected by TypeScript because of separate tsconfig files (can be visible in IDE) but aren't distinguished among the workspaces by Vite on build.
The project uses Yarn 1.x with workspaces, TypeScript 4.9, Vite 3.2, Lerna 6.4 (shouldn't affect the problem at this point)
Project structure is common for a monorepo:
packages/
foo-bar/
src/
index.ts
package.json
tsconfig.json
vite.config.ts
yarn.lock
foo-baz/
(same as above)
foo-shared/
src/
qux.ts
quux.ts
package.json
tsconfig.json
yarn.lock
lerna.json
package.json
tsconfig.json
yarn.lock
When one package (foo-bar
) imports a module from another (foo-shared
):
packages/foo-bar/src/index.ts:
import qux from `@foo/shared/qux';
Another package resolves local aliased imports to wrong package on build, because Vite is unaware of tsconfig aliases:
packages/foo-shared/src/qux.ts:
import quux from `@/quux'; // resolves to packages/foo-bar/src/quux.ts and errors
The error is something like:
[vite:load-fallback] Could not load ...\packages\foo-bar\src/quux (imported by ../foo-shared/src/qux.ts): ENOENT: no such file or directory, open '...\packages\foo-bar\src\stores\quux' error during build:
foo-shared
is currently a dummy package which isn't built standalone, only aliased and used on other packages.
packages/foo-bar/vite.config.ts:
// ...
export default defineConfig({
resolve: {
alias: {
'@': path.join(__dirname, './src'),
'@foo/shared': path.join(__dirname, '../foo-shared/src'),
},
},
/ * some irrelevant options */
});
packages/foo-bar/tsconfig.json and packages/foo-shared/tsconfig.json are similar:
{
"extends": "@vue/tsconfig/tsconfig.web.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@foo/shared/*": ["../foo-shared/src/*"]
},
"typeRoots": [
"./node_modules/@types",
"../../node_modules/@types",
]
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.vue"
],
"exclude": [
"node_modules"
],
}
I tried to replace resolve.alias
with vite-tsconfig-paths
plugin without success. It didn't affect the aliases at all out of the box, and I cannot be sure it's usable for this case.
How can Vite be configured to resolve paths that begin with "@
" to different paths depending on the path of parent module?
@foo/shared
project – Shiller