I'm using a npm workspaces mono repo with two workspaces _common
and le
. My project is React + Vite + TS + Tailwind. I'm using a custom aliasing plugin with vite...
import path from 'path';
import fs from 'fs';
import { Plugin } from 'vite';
const multiAlias = (src: string): Plugin => ({
name: 'multi-alias',
async resolveId(source: string) {
if (source.startsWith('@/')) {
const possiblePaths = [
path.resolve(src, './' + source.replace('@/', '')),
path.resolve(src, '../_common/' + source.replace('@/', '')),
];
for (const p of possiblePaths) {
if (fs.existsSync(p)) {
return p;
}
}
}
return null;
}
});
export default multiAlias;
This plugin allows me to import common components import Carousel from '@/src/Carousel.tsx'
and then surgically overwriting any child component down the dependency tree just by including the same path in my workspace.
This works great when I build my files, however, when I'm developing in VS Code I'm getting the Cannot find module '@/src/Carousel.tsx' or its corresponding type declarations.ts(2307)
in my le
workspace. The same file in my _common
workspace shows no such errors. I'm pretty sure it's because the tsconfig.json isn't setup correctly.
Here is my tsconfig which is used in both workspaces via "extends": "../_common/tsconfig.json",
in the le workspace.
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"baseUrl": "./",
"paths": {
"@/*": ["./*", "../_common/*"],
},
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"allowUnreachableCode": true,
},
"include": ["*.tsx", "src/*.ts", "tokens/*", "../_common/*.tsx", "../_common/src/*.ts", "../_common/tokens/*"],
"references": [{ "path": "./tsconfig.node.json" }]
}
So while debugging a bit further I found that I needed to move my basepath up a directory "baseUrl": "../",
and then name each directory that would be possible for the alias to resolve for the "paths"
object. This is what I ended up with
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"baseUrl": "../",
"paths": {
"@/*": ["./_common/*", "./le/*"],
},
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
},
"include": ["*.tsx", "src/*.ts", "tokens/*"],
"references": [{ "path": "./tsconfig.node.json" }]
}