Skip to content

How to Configure TypeORM to Work in Transpiled JavaScript Code

Express/

You have been developing a TypeScript project using TypeORM without any issues. Finally, you decide it’s time to create a production build. You excitingly transpile the code into JavaScript and try to run it. Oops, an error.

/path/to/project/src/database/entity/UserEntity.ts:1

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

SyntaxError: Cannot use import statement outside a module

Why is the JavaScript build trying to import TypeScript files?

The issue, most likely, is that you have specified in your TypeORM config to only look for .ts files.

// src/database/config.ts

const config = {
  // . . .
  entities: ['src/database/entity/**/*.ts'],
  migrations: ['src/database/migration/**/*.ts'],
};

export default config;

This won’t work when you try to run the JavaScript build with node ./build/index.js. The build version can’t import .ts files.

You can skip to the last part of this post to find a working config file. Continue reading if you want to know more details.

You could try solving this error by creating a separate config for the build version. But be careful, do not specify paths to .js files relative to your config file.

const config = {
  // . . .
  entities: ['./database/entity/**/*.js'], // Bad
  migrations: ['./database/migration/**/*.js'], // Bad
};

if (process.env.NODE_ENV === 'development') {
  Object.assign(config, {
    entities: ['src/database/entity/**/*.ts'],
    migrations: ['src/database/migration/**/*.ts'],
  });
}

Because now you have a different error to deal with.

RepositoryNotFoundError: No repository for "User" was found. Looks like this entity is not registered in current "default" connection?

TypeORM can’t find your entities because the path is actually wrong.

Relative paths don’t work in this case. Node will include files from the path where you ran the node command from.

You can confirm this by inspecting the current working directory inside your config.ts file.

// /path/to/project/src/database/config.ts

const config = {
  // . . .
};

console.log(process.cwd()); // /path/to/project

After you rebuild your application and run node ./build/index.js, you can see process.cwd() returns the root of your project.

You need to specify absolute paths by using __dirname variable.

entities: [`${__dirname}/entity/**/*.js`],
migrations: [`${__dirname}/database/migration/**/*.js`],

The __dirname will return a path to the directory of the file that uses this variable.

The Clean Solution

You can combine all the things you have learned in one config. This will get TypeORM to work while developing with TypeScript and while running the JavaScript build.

const config = {
  // . . .
  entities: [`${__dirname}/entity/**/*{.js,.ts}`],
  migrations: [`${__dirname}/migration/**/*{.js,.ts}`],
};

export default config;

When you use *{.js,.ts} you tell TypeORM to look for both TypeScript and JavaScript files.

Using the __dirname variable gets you the correct path. While developing, it points to the source code. But, when running the transpiled JavaScript version, it points to the build folder.