I have a Vite library using Vitest and Zod. Given the following folder structure
.
├── src
│ ├── leading
│ │ ├── index.ts ( 2 )
│ │ └── leadingDataSourceConfigurationSchema.ts
│ ├── index.ts ( 1 )
│ └── dataSourceConfigurationSchema.ts
└── test
└── my.spec.ts
I created a base schema for data sources
import { z } from 'zod';
const dataSourceConfigurationSchema = z.object({
id: z.string().min(1)
}).strict();
export { dataSourceConfigurationSchema };
exported by the index.ts ( 1 )
export * from "./leading";
export { dataSourceConfigurationSchema } from "./dataSourceConfigurationSchema";
I also have a schema extending the one above
import { z } from 'zod';
import { dataSourceConfigurationSchema } from '..';
const leadingDataSourceConfigurationSchema = dataSourceConfigurationSchema.extend({
entityTypeId: z.string().min(1),
}).strict();
export { leadingDataSourceConfigurationSchema };
the index.ts ( 2 ) only exports this schema
export { leadingDataSourceConfigurationSchema } from "./leadingDataSourceConfigurationSchema";
When creating a test file like so
import { describe, it, expect } from 'vitest';
import { ZodError } from 'zod';
import { leadingDataSourceConfigurationSchema } from '../src';
describe('test', () => {
it('fails.', () => {
expect(() => leadingDataSourceConfigurationSchema.parse({})).toThrow(ZodError);
});
});
the test fails with the following error message
TypeError: Cannot read properties of undefined (reading 'extend')
This problem might be related to
When replacing the import
import { dataSourceConfigurationSchema } from '..';
with
import { dataSourceConfigurationSchema } from '../dataSourceConfigurationSchema';
the test passes. So it seems the project is struggling with circular dependencies?
Do sub directories have to import files directly or can I fix this problem with a different approach?
Yes, you have a circular dependency, and due to the import order dataSourceConfigurationSchema
will not yet be initialised when leadingDataSourceConfigurationSchema
is intialised. This is not an issue of zod or vite (although with a proper ES6 module implementation, you'd get a TDZ error instead of a reference error from accessing a method on undefined
).
As you saw, you can fix this by importing dataSourceConfigurationSchema
directly from ../dataSourceConfigurationSchema.ts and not from ../index.ts, the module that imports leadingDataSourceConfigurationSchema.ts itself.
Another solution would be to change the order of imports in src/index.ts to
export { dataSourceConfigurationSchema } from "./dataSourceConfigurationSchema";
export * from "./leading";
but this is really fragile, so I wouldn't recommend it.