swc-project / swc-node

Faster ts-node without typecheck
MIT License
1.81k stars 75 forks source link

Directory import is not supported resolving ES modules #786

Closed TArch64 closed 4 months ago

TArch64 commented 5 months ago

Hi guys. I'm trying to run a nest.js app in ESM mode with typescript but it fails on importing directories using index files. When I use commonjs everything works file except an esm only library which I'm trying to use 🫠

Here is the the code & error.

import { MicroserviceHybridStarter } from '@minino-api/core/microservices';
import { GatewayModule } from './GatewayModule';

MicroserviceHybridStarter.start(GatewayModule);
api-gateway-1  | > @minino/api@ dev /app/packages/api
api-gateway-1  | > SWCRC=true node --import @swc-node/register/esm-register --enable-source-maps --watch --watch-preserve-output --inspect=0.0.0.0:3001 apps/$APP/src/main.ts
api-gateway-1  |
api-gateway-1  | Debugger listening on ws://0.0.0.0:3001/519170d9-6ac3-4e51-9f4a-7675310df9f5
api-gateway-1  | For help, see: https://nodejs.org/en/docs/inspector
api-gateway-1  |
api-gateway-1  | node:internal/modules/run_main:129
api-gateway-1  |     triggerUncaughtException(
api-gateway-1  |     ^
api-gateway-1  | Error [ERR_UNSUPPORTED_DIR_IMPORT]: Directory import '/app/packages/api/libs/core/src/microservices' is not supported resolving ES modules imported from /app/packages/api/apps/gateway/src/main.ts
api-gateway-1  |     at finalizeResolution (node:internal/modules/esm/resolve:259:11)
api-gateway-1  |     at moduleResolve (node:internal/modules/esm/resolve:933:10)
api-gateway-1  |     at defaultResolve (node:internal/modules/esm/resolve:1157:11)
api-gateway-1  |     at nextResolve (node:internal/modules/esm/hooks:866:28)
api-gateway-1  |     at resolve (/app/node_modules/.pnpm/@swc-node+register@1.9.2_@swc+core@1.5.27_@swc+types@0.1.8_typescript@5.4.5/node_modules/@swc-node/register/esm.mts:22:12)
api-gateway-1  |     at nextResolve (node:internal/modules/esm/hooks:866:28)
api-gateway-1  |     at Hooks.resolve (node:internal/modules/esm/hooks:304:30)
api-gateway-1  |     at MessagePort.handleMessage (node:internal/modules/esm/worker:196:24)
api-gateway-1  |     at [nodejs.internal.kHybridDispatch] (node:internal/event_target:825:20)
api-gateway-1  |     at MessagePort.<anonymous> (node:internal/per_context/messageport:23:28) {
api-gateway-1  |   code: 'ERR_UNSUPPORTED_DIR_IMPORT',
api-gateway-1  |   url: 'file:///app/packages/api/libs/core/src/microservices'
api-gateway-1  | }
api-gateway-1  |
api-gateway-1  | Node.js v20.14.0
api-gateway-1  | Failed running 'apps/gateway/src/main.ts'
My swcrc ```json { "$schema": "https://swc.rs/schema.json", "module": { "type": "nodenext", "ignoreDynamic": true }, "jsc": { "parser": { "syntax": "typescript", "decorators": true, "decoratorsBeforeExport": true }, "baseUrl": "./", "paths": { "@minino-api/core": ["libs/core/src"], "@minino-api/core/*": ["libs/core/src/*"], "@minino-api/database": ["libs/database/src"], "@minino-api/database/*": ["libs/database/src/*"], "@minino-api/trpc": ["trpc"], "@minino-api/trpc/*": ["trpc/*"] }, "transform": { "decoratorMetadata": true } } } ```
My tsconfig ```json { "compilerOptions": { "module": "ESNext", "moduleResolution": "bundler", "target": "ESNext", "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "verbatimModuleSyntax": true, "isolatedModules": true, "sourceMap": true, "outDir": "./dist", "baseUrl": "./", "incremental": true, "skipLibCheck": true, "strictNullChecks": true, "noImplicitAny": false, "strictBindCallApply": false, "forceConsistentCasingInFileNames": false, "noFallthroughCasesInSwitch": false, "paths": { "@minino-api/core": ["libs/core/src"], "@minino-api/core/*": ["libs/core/src/*"], "@minino-api/database": ["libs/database/src"], "@minino-api/database/*": ["libs/database/src/*"], "@minino-api/trpc": ["trpc"], "@minino-api/trpc/*": ["trpc/*"] } }, "include": ["apps", "libs", "trpc"] } ```
My workspace package json ```json { "name": "@minino/api", "private": true, "type": "module", "scripts": { "build": "nest build", "dev": "SWCRC=true node --import @swc-node/register/esm-register --enable-source-maps --watch --watch-preserve-output --inspect=0.0.0.0:3001 apps/$APP/src/main.ts", "db:studio": "drizzle-kit studio --host 0.0.0.0 --port 3001", "db:migration-init": "drizzle-kit generate", "db:migration-drop": "drizzle-kit drop", "db:migration-run": "SWCRC=true node --import @swc-node/register/esm-register --enable-source-maps libs/database/drizzle/migrate.ts" }, "files": [ "./trpc", "apps/gateway" ], "dependencies": { "@auth/core": "^0.32.0", "@auth/drizzle-adapter": "^1.2.0", "@nestjs/cli": "^10.3.2", "@nestjs/common": "^10.3.9", "@nestjs/config": "^3.2.2", "@nestjs/core": "^10.3.9", "@nestjs/microservices": "^10.3.9", "@nestjs/platform-express": "^10.3.9", "@nestjs/schematics": "^10.1.1", "@trpc/server": "^10.45.2", "@types/express": "^4.17.17", "@types/node": "^20.14.2", "@types/pg": "^8.11.6", "drizzle-kit": "^0.22.7", "drizzle-orm": "^0.31.2", "ioredis": "^5.4.1", "pg": "^8.12.0", "reflect-metadata": "^0.2.2", "rxjs": "^7.8.1", "typescript": "^5.4.5" }, "devDependencies": { "@swc-node/register": "^1.9.2" } } ```
TArch64 commented 5 months ago

Okay. I managed to fix directory import by adding a "resolveFully" which is not easy to find because there is no such option in the swcrc schema, however it fails to import pg package

api-gateway-1  | Restarting 'apps/gateway/src/main.ts'
api-gateway-1  | Debugger listening on ws://0.0.0.0:3001/f9c4d151-d9fd-4dc2-bb7d-b1ea8a43bf82
api-gateway-1  | For help, see: https://nodejs.org/en/docs/inspector
api-gateway-1  | /app/packages/api/libs/database/src/PostgresClient.ts:1
api-gateway-1  | import { Client } from 'pg';
api-gateway-1  |          ^
api-gateway-1  |
api-gateway-1  | SyntaxError: The requested module 'pg' does not provide an export named 'Client'
api-gateway-1  |     at ModuleJob._instantiate (node:internal/modules/esm/module_job:134:21)
api-gateway-1  |     at async ModuleJob.run (node:internal/modules/esm/module_job:217:5)
api-gateway-1  |     at async ModuleLoader.import (node:internal/modules/esm/loader:316:24)
api-gateway-1  |     at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:123:5)
api-gateway-1  |
api-gateway-1  | Node.js v20.14.0
api-gateway-1  | Failed running 'apps/gateway/src/main.ts'
TArch64 commented 5 months ago

The issue with pg package occurs because all exports of the package wrapped into "default" property so instead of { Client: ... } it has { default: { Client: ... } }

Brooooooklyn commented 4 months ago

@TArch64 Should be fixed in https://github.com/swc-project/swc-node/pull/806

TArch64 commented 4 months ago

Thank you. I managed to make everything working so I'm closing the issue. I hope new nodejs option for importing esm from commonjs will make things easier