How to deal with "Cannot use import statement outside a module" error in Node.js + TypeORM seeding case?

2.8k views Asked by At

I got the error

[cause]: Error: Unable to open file: "D:\IntelliJ IDEA***\TypeORM_DataSource.ts". Cannot use import statement outside a module

error when tried to run the seeders by

typeorm-seeding \
  --dataSource 01-Source/Implementation/Elements/DataBase/TypeORM_DataSource.ts \
  seed 01-Source/Implementation/Elements/DataBase/Seeders/*.ts

using @jorgebodega/typeorm-seeding.

Well, it is the frequent error with ts-node, but each time the cause thus the solution are different. In my case, the adding of "type": "module" to package.json does not solve the problem.

By the way, the TypeORM migrations works fine:

typeorm-ts-node-esm migration:generate ./01-Source/Implementation/Elements/DataBase/Migrations/Initialization -d ./01-Source/Implementation/Elements/DataBase/TypeORM_DataSource.ts

Train of thought about cause

In the documentation, the example with .ts has been gave:

typeorm-seeding seed -d path/to/datasource src/seeders/*.ts

Thus, typeorm-seeding must have the build-in TypeScript support. Most likely, it is using the ts-node.

The usage of export/imports keywords is completely basic scenario for the TypeScript. Into what it will be transpiled - the different question. Should not the typeorm-seeding care about transpiling of the input TypeScript to appropriate types of modules?

Appendix

TypeScript configuration

Theoretically, the ts-node settings should solve the issues with modules type.

{

  "compilerOptions": {

    "target": "ESNext",
    "module": "ESNext",
    "moduleResolution": "node",
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,

    "strict": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "experimentalDecorators": true,

    "emitDecoratorMetadata": true,

    "baseUrl": "./01-Source",
    "paths": {
      "@CommonSolution/*": [ "./CommonSolution/*"],
      /* ... */
    }
  },

  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    },
    "require": [
      "tsconfig-paths/register"
    ]
  }

}

docker-compose.yaml

version: "3.5"

services:

  Database:

    image: postgres
    container_name: Example-Local-Database
    ports:
      - "${DATABASE_PORT}:${DATABASE_PORT}"

    environment:
      - "POSTGRES_PASSWORD=${DATABASE_PASSWORD}"

    volumes:
      - DatabaseData:/var/lib/postgresql/data

  # ...

volumes:
  DatabaseData:
    name: Example-Local-DatabaseData
    driver: local

1

There are 1 answers

2
Dimava On

You are using

  "ts-node": {
    "compilerOptions": {
      "module": "CommonJS"
    },
    "require": [
      "tsconfig-paths/register"
    ]
  }

while the thing "type": "module" in package.json does is switching node from the commonjs modules to esnext, so you are now trying to import CommonJS module as ESNext which may causes the error

Try to remove it for "module": "CommonJS" from ts-node compilerOptions


I recommend trying https://github.com/esbuild-kit/tsx as a more modern and stable alternative to ts-node. It "just works" in most of cases.