5

I've set up a Typescript project with TypeORM and I am facing some issues with the compilation.

My package structure is like this:

root
├── db
│   ├── migrations
│   │   ├── a_migration.ts
│   ├── connection
│   │   ├── config.ts <- ormconfig
│   │   ├── encrypt.ts
│   │   ├── index.ts <- creates the connection
├── src
│   ├── card
│   │   ├── entity.ts
├── package.json
├── tsconfig.json

My config.ts is:


export = {
  type: 'postgres',
  host: POSTGRES_HOST,
  port: POSTGRES_PORT,
  username: POSTGRES_USER,
  password: POSTGRES_PASS,
  database: POSTGRES_DB,
  synchronize: true,
  logging: false,
  entities: ['**src/**/*entity.{ts,js}'],
  migrations: ['**/migrations/*.{ts,js}'],
  cli: {
    entitiesDir: 'src/entity',
    migrationsDir: 'db/migrations',
  },
  namingStrategy: new SnakeNamingStrategy(),
};

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es6",
    "module": "CommonJS",
    "allowJs": false,
    "esModuleInterop": true,
    "noImplicitAny": true,
    "resolveJsonModule": true,
    "outDir": "./build",
    "strict": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  },
  "include": ["./src/*", "./db/*"],
  "exclude": ["./**/__tests__/*", "./**/__functionaltests__/*"]
}

I tried replacing the ** prefix in entities & migrations with a path.join + __dirname but then typeorm could not detect the migration files and the entities. I understand this has something to do with the path resolving where the code ends up under the build folder but I am not sure how I can tackle this.

If I live it like this the CLI works for the uncompiled code (ts) executing the app with something like nodemon but not for the compiled (js) one.

The error I am getting from the compiled js is the: SyntaxError: Cannot use import statement outside a module

Any help is appreciated, thanks a lot!

3 Answers 3

5

Your entities and migrations should be given the build directory instead of the src directory.

And synchronize should set as false.

Try to update your config.ts like below:

export = {
  type: 'postgres',
  host: POSTGRES_HOST,
  port: POSTGRES_PORT,
  username: POSTGRES_USER,
  password: POSTGRES_PASS,
  database: POSTGRES_DB,
  synchronize: false,
  logging: false,
  entities: ['build/src/**/*entity.{ts,js}'],
  migrations: ['build/db/migrations/*.{ts,js}'],
  cli: {
    entitiesDir: 'src/entity',
    migrationsDir: 'db/migrations',
  },
  namingStrategy: new SnakeNamingStrategy(),
};

Note the changes in entities and migrations properties. If this did not work, most probably it might be due to the paths I specified are not inside the build directory. In that case, change those as necessary.

Hope this helps you! Cheers 🍻 !!!

Sign up to request clarification or add additional context in comments.

7 Comments

Hi, thanks for your help and sorry for the late response. This will work inside a docker container but it won't be able to run on local env without docker like (nodemon and ts-node). If you have any additional suggestions, they are more than welcome 😁
In local environment, you need to build the app before running the migrations. Did you try “npm run build” before running the migrations? What is the error you’re getting in the local environment? Oh and by the way, you need to set synchronize to false because otherwise there won’t be any changes to create migrations for.
the issue with that is not on the migration execution but on the app run via typescript. I mean if I run it on dev mode for hot reload, etc the app won't be able to find the migrations and entity files. Not sure if I make any sense 😅
What is the npm command you use to run this in dev mode?
I am using nodemon for that and the nodemon exec is ts-node ./src/app.ts.
|
1

I encountered a similar problem, perhaps this might help you.

I am using a (uncompiled) ormconfig.js (note, .js) for migrations like this (the NestJS application uses another way to establish its DB connection via TypeORM):

const { SnakeNamingStrategy } = require('typeorm-naming-strategies');

module.exports = {
    type: 'mysql',
    host: 'localhost',
    username: 'some user',
    database: 'some db',
    password: 'some pw',
    entities: ['./src/**/model/*.entity.ts'],
    migrations: ['migrations/*{.ts,.js}'],
    cli: {
        migrationsDir: 'src/migrations',
    },
    namingStrategy: new SnakeNamingStrategy(),
};

My IDE suggests to convert this to an ES6 module, which changes the require('typeorm-naming-strategies') into an import statement. And if I do so, I will get:

SyntaxError: Cannot use import statement outside a module

Additional output to the error is:

import { SnakeNamingStrategy } from 'typeorm-naming-strategies';
^^^^^^

So perhaps you can replace your (not shown?) import of SnakeNamingStrategy to a require.

Just a guess, not sure if it does really help you.

Comments

0

Create environment variables for your deployments. In config.ts check the env then set entities and migrations accordingly.

1 Comment

Can you provide details about your suggestion?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.