drizzle-team / drizzle-orm

Headless TypeScript ORM with a head. Runs on Node, Bun and Deno. Lives on the Edge and yes, it's a JavaScript ORM too 😅
https://orm.drizzle.team
Apache License 2.0
24.74k stars 654 forks source link

Issues with ESBuild Register #3308

Open mothershipper opened 6 months ago

mothershipper commented 6 months ago

There's an issue with esbuild-register that's impacting our ability to use drizzle-kit, the TL;DR; is esbuild-register doesn't seem to resolve the project's tsconfig file correctly.

Did some instrumenting and observed that it fails to bubble up looking for a tsconfig.json for the project when running drizzle-kit:

Reading config file '/Users/jack/dev/marketplace/backend/libs/database/drizzle.config.ts'
loading /Users/jack/dev/marketplace/backend/libs/database/tsconfig.json
loading /Users/jack/dev/marketplace/backend/configs/tsconfig.json
loading /Users/jack/dev/marketplace/backend/configs/tsconfig.json
loading /Users/jack/dev/marketplace/backend/configs/tsconfig.json
loading /Users/jack/dev/marketplace/backend/configs/tsconfig.json
loading /Users/jack/dev/marketplace/backend/configs/tsconfig.json
loading /Users/jack/dev/marketplace/backend/configs/application/tsconfig.json
Error: Transform failed with 4 errors:
 ... ERROR: Transforming JavaScript decorators to the configured target environment ("es2021") is not supported yet

It seems like esbuild-register searches the local directory of the file under compilation for a tsconfig.json, and if not found, uses the default tsconfig settings. Our problem is that backend is a nest project that makes heavy use of decorators. experimentalDecorators is not a default tsconfig option and hence esbuild fails to compile the drizzle config file.

The original esbuild-register issue suggested this can be worked around by doing the tsconfig resolution yourself and passing that as an option to esbuild, bypassing its resolution of the tsconfig.json.

mothershipper commented 6 months ago

I think misread the proposed solution on the downstream issue. It seems like they were suggesting parsing the complete tsconfig file yourself to pass individual options to esbuild, which is roughly what was proposed in a different tsconfig handling issue: https://github.com/egoist/esbuild-register/issues/99

Not sure if this is fixable without fixing upstream or forking esbuild-register :/

mothershipper commented 6 months ago

For a bit more color, esbuild-register uses transformSync from esbuild. According to the docs, the transform API does not have access to the file-system

Seems like you'd have to load the tsconfig.json, handle any extends and pass a merged tsconfig.json down to esbuild for the transformSync call.

AlexBlokh commented 6 months ago

@mothershipper thanks for reporting, can you please prepare a simple minimal repro example, we'll gladly have a look

mothershipper commented 6 months ago

@AlexBlokh https://github.com/mothership/drizzle-kit-esbuild-bug

LynchEntrostat commented 5 months ago

Hi, I am also experiencing the same issue. My project uses class-transformer decorators on some classes that aren't even imported in my drizzle entity files, but I do get this error when trying to generate a migration.

peterphan1996 commented 5 months ago

I also have this issue using NestJS

LynchEntrostat commented 5 months ago

Hi, I am also experiencing the same issue. My project uses class-transformer decorators on some classes that aren't even imported in my drizzle entity files, but I do get this error when trying to generate a migration.

My team and I temporarily solved this on my NestJS project using a patch

drizzle-kit@0.22.1.patch

diff --git a/bin.cjs b/bin.cjs
index e5e7558dc577c4fba1ca4fe508a5851b4e8f4c91..ddb3a33904dd375bfbb39be5dcc5cfc376226faa 100755
--- a/bin.cjs
+++ b/bin.cjs
@@ -1,5 +1,7 @@
 #!/usr/bin/env node
 "use strict";
+require('ts-node/register');
+require('reflect-metadata');
 var __create = Object.create;
 var __defProp = Object.defineProperty;
 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
LynchEntrostat commented 5 months ago

Hi, I am also experiencing the same issue. My project uses class-transformer decorators on some classes that aren't even imported in my drizzle entity files, but I do get this error when trying to generate a migration.

My team and I temporarily solved this on my NestJS project using a patch

drizzle-kit@0.22.1.patch

diff --git a/bin.cjs b/bin.cjs
index e5e7558dc577c4fba1ca4fe508a5851b4e8f4c91..ddb3a33904dd375bfbb39be5dcc5cfc376226faa 100755
--- a/bin.cjs
+++ b/bin.cjs
@@ -1,5 +1,7 @@
 #!/usr/bin/env node
 "use strict";
+require('ts-node/register');
+require('reflect-metadata');
 var __create = Object.create;
 var __defProp = Object.defineProperty;
 var __getOwnPropDesc = Object.getOwnPropertyDescriptor;

@peterphan1996 Hope this helps you too.

artandrey commented 4 months ago

I encountered the same issue in my NestJS project.

Reason: The issue was caused by importing an enum from the same file as a class with decorators. The enum was used to type the Drizzle schema.

Solution: I moved the enum to a separate file, which allowed me to avoid importing code that includes decorators into my schema. After this migration, the schema was generated successfully.

As we can see, @mothershipper provided an example repository with the same issue: the Drizzle config imports a class, DatabaseConfig, that contains decorators:

// other imports ...
import { load, loadEnvFile, DatabaseConfig } from './config' // import that causes error (DatabaseConfig class contains decorators)

const dbConfig: DatabaseConfig = load(DatabaseConfig)

export default defineConfig({
  // config ...
})

To sum up, just remove all imports containing decorators from your drizzle schema and drizzle config