I'm trying to build a monorepo around my SvelteKit app, where the app and various monorepo packages are all written in TypeScript.
The SvelteKit app works fine, until I try to symlink in one specific package from the monorepo. The problem package depends on @redis/client (which I would expect to be very reliable) and the error message references that module:
ReferenceError: exports is not defined at /@fs/Users/me/project/node_modules/.pnpm/@[email protected]/node_modules/@redis/client/dist/index.js:16:23 at instantiateModule (file:///Users/me/project/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-ca21228b.js:52420:15)
If I instead publish the monorepo packages to our private github package registry, and install them from there, it works fine... so I would think that the way I'm building my TS packages is ok... But for reference, here's a snippet from the package.json of the package that depends on @redis/client:
"type": "module",
"types": "dist/index.d.ts",
"exports": {
"import": "./dist/index.js",
"require": "./dist/index.cjs"
},
and the tsconfig from the same package:
{
"compilerOptions": {
"target": "es6", //also tried ES2022
"module": "commonjs", //also tried ES2022
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"noUncheckedIndexedAccess": true,
"noEmit": true,
"moduleResolution": "node"
}
}
The SvelteKit app, as is typical, has type=module in its package.json, and uses Vite. The vite config is pretty vanilla:
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vitest/config';
export default defineConfig({
plugins: [sveltekit()],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
}
});
It does use a slightly different tsconfig, which was generated for me by the SvelteKit new-app wizard:
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"ignoreDeprecations": "5.0"
}
}
Since it works if the packages are published to a private package repo and installed as usual using pnpm, I have to believe this is some sort of Vite configuration issue.
I've tried every permutation that I can think of to get the Vite config's optimizeDeps.include and/or build.commonjsOptions.include settings to fix this, based on a suggestion from someone in a discord server; but I haven't seen anything change. I'm not even sure if that's barking up the right tree.
I have created the smallest possible reproduction case here, including a list of the steps I took to create the repro, in the order that I took them.
If you're looking at the repro code and asking yourself why I would want to wrap @redis/client like this, the answer is in all of the stuff that I'm omitting for business reasons, repro-brevity, etc. I assure you it needs to be done this way; but the tl;dr is that the
getRedismethod in the real project accepts some arguments that define what environment and what customer (e.g. ABC, production) we want to connect the redis client to, and it looks up the correct configuration and returns a connected client.