Given a tsconfig file with es6 target and the following typeorm config :
{
...
entities: ['apps/api/**/**.entity.ts'],
migrations: ['apps/api/migrations/*.ts'],
migrationsRun: true
...
}
When I start the nestjs application
I get the following error when typeorm tries to load the entities
[Nest] 21470 - 2019-05-25 10:18 [NestFactory] Starting Nest application...
[Nest] 21470 - 2019-05-25 10:18 [InstanceLoader] AppModule dependencies initialized +129ms
[Nest] 21470 - 2019-05-25 10:18 [InstanceLoader] CoreModule dependencies initialized +9ms
[Nest] 21470 - 2019-05-25 10:18 [InstanceLoader] TypeOrmModule dependencies initialized +1ms
[Nest] 21470 - 2019-05-25 10:18 [InstanceLoader] PubSubModule dependencies initialized +2ms
[Nest] 21470 - 2019-05-25 10:18 [InstanceLoader] PassportModule dependencies initialized +7ms
[Nest] 21470 - 2019-05-25 10:18 [InstanceLoader] JwtModule dependencies initialized +1ms
[Nest] 21470 - 2019-05-25 10:18 [InstanceLoader] GraphQLModule dependencies initialized +1ms
[Nest] 21470 - 2019-05-25 10:18 [TypeOrmModule] Unable to connect to the database. Retrying (1)... +152ms
/Users/jonjon/work/nx/typefaster/apps/api/src/app/features/content/content.entity.ts:1
(function (exports, require, module, __filename, __dirname) { import * as GQL from '@tf/apps/api/typings/graphql';
^
SyntaxError: Unexpected token *
at new Script (vm.js:80:7)
at createScript (vm.js:274:10)
at Object.runInThisContext (vm.js:326:10)
at Module._compile (internal/modules/cjs/loader.js:664:28)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
Then I tried to use entity classes directly instead of putting the paths :
entities: ['apps/api/**/**.entity.ts'] -->
entities: [UserEntity, ContentEntity, RandomEntity, RecordEntity]
Now I get the following error but for typeorm migrations :
[Nest] 21543 - 2019-05-25 10:27 [NestFactory] Starting Nest application...
[Nest] 21543 - 2019-05-25 10:27 [InstanceLoader] AppModule dependencies initialized +155ms
[Nest] 21543 - 2019-05-25 10:27 [InstanceLoader] CoreModule dependencies initialized +1ms
[Nest] 21543 - 2019-05-25 10:27 [InstanceLoader] TypeOrmModule dependencies initialized +1ms
[Nest] 21543 - 2019-05-25 10:27 [InstanceLoader] PubSubModule dependencies initialized +1ms
[Nest] 21543 - 2019-05-25 10:27 [InstanceLoader] PassportModule dependencies initialized +1ms
[Nest] 21543 - 2019-05-25 10:27 [InstanceLoader] JwtModule dependencies initialized +16ms
[Nest] 21543 - 2019-05-25 10:27 [InstanceLoader] GraphQLModule dependencies initialized +1ms
[Nest] 21543 - 2019-05-25 10:27 [TypeOrmModule] Unable to connect to the database. Retrying (1)... +171ms
/Users/jonjon/work/nx/typefaster/apps/api/migrations/1551728841387-Migration.ts:1
(function (exports, require, module, __filename, __dirname) { import {MigrationInterface, QueryRunner} from "typeorm";
^
SyntaxError: Unexpected token {
at new Script (vm.js:80:7)
at createScript (vm.js:274:10)
at Object.runInThisContext (vm.js:326:10)
at Module._compile (internal/modules/cjs/loader.js:664:28)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
Please provide any relevant information about your setup:
Any updates on this issue?
@jon301 any update on this issue?
were you able to fix it?
Sorry for the late reply. Could you provide a repo with repro?
@vsavkin I think I have a repro here:
https://github.com/beeman/nestjs-typeorm-nx/tree/beeman/typeorm-error
[Nest] 55008 - 07/13/2019, 8:31 PM [NestFactory] Starting Nest application...
[Nest] 55008 - 07/13/2019, 8:31 PM [InstanceLoader] ApiCoreModule dependencies initialized +352ms
[Nest] 55008 - 07/13/2019, 8:31 PM [InstanceLoader] ApiUserModule dependencies initialized +3ms
[Nest] 55008 - 07/13/2019, 8:31 PM [InstanceLoader] AppModule dependencies initialized +4ms
[Nest] 55008 - 07/13/2019, 8:31 PM [ExceptionHandler] Unexpected token { +134ms
/opt/colmena/oss/nestjs-typeorm-nx/libs/api/user/src/lib/entities/user.entity.ts:1
import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
^
SyntaxError: Unexpected token {
at Module._compile (internal/modules/cjs/loader.js:760:23)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:827:10)
at Module.load (internal/modules/cjs/loader.js:685:32)
at Function.Module._load (internal/modules/cjs/loader.js:620:12)
at Module.require (internal/modules/cjs/loader.js:723:19)
at require (internal/modules/cjs/helpers.js:14:16)
at Function.PlatformTools.load (/opt/colmena/oss/nestjs-typeorm-nx/src/platform/PlatformTools.ts:129:28)
at /opt/colmena/oss/nestjs-typeorm-nx/src/util/DirectoryExportedClassesLoader.ts:32:36
at Array.map (<anonymous>)
at Object.importClassesFromDirectories (/opt/colmena/oss/nestjs-typeorm-nx/src/util/DirectoryExportedClassesLoader.ts:32:10)
I'm also experiencing this issue. Have there been any update on this?
I fixed this by changing my entities in my ormconfig.ts
from:
entities: ['apps/**/*.entity.ts']
to:
entities: [join(__dirname, './**/*.entity{.ts,.js}')],
Make sure you have import { join } from 'path';
You can also "fix" this issue by instead of supplying globs to the entities array, you supply the entities directly.
entities: [User, Product]
However this would require extra steps to introduce an entity. (Can be eased with using an index.ts and combining exports)
I'm also experiencing this issue. any updates on this?
Talked to @FrozenPandaz about it. The issue is because we bundle the nest app.
We have a plan in mind. It should be addressed by Nx 9.
This fixed it for me:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { getMetadataArgsStorage } from 'typeorm';
import { typeOrmConfig } from '../config/typeorm.config';
@Module({
imports: [
...,
TypeOrmModule.forRoot({
...typeOrmConfig,
entities: getMetadataArgsStorage().tables.map(tbl => tbl.target)
})
]
})
export class AppModule {}
According to the docs https://docs.nestjs.com/techniques/database all you enter is
entities: [__dirname + '/**/*.entity{.ts,.js}'],
Which gives an error noting that it cannot find any of your entity.ts files
No repository for "Post" was found. Looks like this entity is not registered in current "default" connection?
Dumping __dirname reveals it is running in the dist/app/xyz folder, which means you would have to use entities: [__dirname + '/../../../app/xyz/src/app/**/*.entity{.ts,.js}'],
But I can confirm that @NailRode suggestion of entities: getMetadataArgsStorage().tables.map(tbl => tbl.target) works for me.
Hi folks! I've reclassified this issue as an enhancement as the solution we're going to pursue is creating a builder for running ts-node.
The reason that the repro provided by @beeman (thanks!) doesn't work is that the node process can't read ts files directly. Providing a ts-node builder should mean that this approach will work in future.
If you can't wait for the builder implementation, I recommend that, for the moment, you try one of the workarounds which involve importing your entity files so that they don't get referenced as uncompiled typescript.
Smol update on this - I've got a builder working with ts-node-dev (this has some nicer watch functionality over plain ts-node) but there are some rough edges to deal with. It works on @beeman's repro repo though.
What's the current status for a ts-node builder in Nx? What could be done to help?
@fknop (and anyone else following this thread) - Getting the ts-node-dev/ts-node builder running is straightforward (ish), what we're currently questioning is whether this is the kind of builder that fits in the Nx core libraries.
It's something that could only ever be used in a development capacity. The fact that it "fixes" this particular issue may be more down to how Nest itself works.
The basic changes necessary are in this commit here (which inexplicably also tries to add tests for the linter builder) - https://github.com/jdpearce/nx/commit/d9b371af286b273df72772557f5ccd02e6d5cfcc
@vsavkin may well have the final say on whether we want to include this functionality or not.
Dear everyone in this thread,
i managed to solve the migrations issue in my nrwl/nx application. This is, what i did:
1) (optional!) install scripty (https://github.com/testdouble/scripty), which lets you execute shell-scripts from npm; npm install --save-dev scripty. While this step is optional, it makes your life easier
2) add a few npm scripts to your package.json file to easily trigger the commands:
{
// ...
scripts : {
// ...
"migrate:create": "scripty",
"migrate:run": "scripty"
}
}
Note that those npm scripts just call the previous mentioned scripty library.
3) Create the proper scripty shell scripts: in your root folder (next to the package.json file) create a scripts folder. This folder is "crawled" by scripty when invoking a npm script. For example, if your command is called migrate:create (see step 2), you need to create a file in scripts/migrate/create.sh.
scripts/migrate/create.sh
#!/usr/bin/env sh
cd ./apps/"$1"/src
npx typeorm migration:create -n "$2"
scripts/migrate/run.sh
#!/usr/bin/env sh
cd ./apps/"$1"/src
npx tsc database/migrations/src/*.ts --outDir database/migrations/generated
npx typeorm migration:run
4) add an ormconfig.js file into the root directory of your application that works with a database. As your mono-repository may contain multiple apps that interact with databases, you may want to have different ormconfig.js files.
apps/api/src/ormconfig.js
module.exports = {
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'databaseuser',
password: 'databasepassword',
database: 'databasename',
migrationsTableName: 'migrations',
migrations: ['database/migrations/generated/*.js'],
cli: {
migrationsDir: 'database/migrations/src',
},
synchronize: false,
};
5) To create a new migration, call
# npm run migrate:create PROJECTNAME MIGRATIONNAME
npm run migrate:create api CreateUsersTable
This will create a new file apps/api/src/database/migrations/src/123456789-CreateUsersTable.ts. You can now fill this migration with life!
6) To run (i.e., execute) all migrations and replicate them to the database, you can call
# npm run migrate:run PROJECTNAME
npm run migrate:run api
This command will first transpile all existing apps/api/src/database/migrations/src/*.ts into javascript and store them in apps/api/src/database/migrations/generated. The latter are then executed by typeorm.
I hope this solution works for you guys!
If you use VSCode, you can create a .vscode/tasks.json file in your project (top level) and add the following content there:
./.vscode/tasks.json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "migration:create",
"type": "shell",
"command": "npm run migrate:create ${input:availableApps} -n ${input:userInput}"
},
{
"label": "migration:run",
"type": "shell",
"command": "npm run migrate:run ${input:availableApps}"
}
],
"inputs": [
{
"type": "promptString",
"id": "userInput",
"description": "Enter a Value"
},
{
"type": "pickString",
"id": "availableApps",
"description": "Select a nrwl/nx app to debug?",
"options": ["appA", "appB", "appC"]
}
]
}
Now you can simply use the VSCode Task Runner (Press F1, Select "Task: Run" and then select the defined Task). This will show you some nice GUI elements to select / input the proper information. Please note that you need to adapt the available Options in the availableApps input!
You can also "fix" this issue by instead of supplying globs to the
entitiesarray, you supply the entities directly.entities: [User, Product]However this would require extra steps to introduce an entity. (Can be eased with using an index.ts and combining exports)
P.s.: And while this is (IMHO) acceptable for entities, it's not for migrations.
Thats works partially, i have 3 entries:
// catalog-brand.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { CatalogItem } from './catalog-item.entity';
@Entity()
export class CatalogBrand {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 500 })
name: string;
@OneToMany(
type => CatalogItem,
ci => ci.brand
)
items: CatalogItem[];
}
// catalog-type.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, OneToMany } from 'typeorm';
import { CatalogItem } from './catalog-item.entity';
@Entity()
export class CatalogType {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 500 })
name: string;
@OneToMany(
type => CatalogItem,
ci => ci.type
)
items: CatalogItem[];
}
and
// catalog-item.entity.ts
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne } from 'typeorm';
import { CatalogType } from './catalog-type.entity';
import { CatalogBrand } from './catalog-brand.entity';
@Entity('catalog')
export class CatalogItem {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 100 })
name: string;
@Column({ length: 500 })
description: string;
@ManyToOne(
t => CatalogBrand,
cb => cb.items
)
brand: CatalogBrand;
@ManyToOne(
t => CatalogType,
ct => ct.items
)
type: CatalogType;
}
and i got this error:
/Users/gperdomor/Developer/eshop/dist/apps/catalog-api/main.js:222
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CatalogBrand", function() { return CatalogBrand; });
^
ReferenceError: Cannot access 'CatalogBrand' before initialization
at Module.CatalogBrand (/Users/gperdomor/Developer/eshop/dist/apps/catalog-api/main.js:222:104)
at Module../apps/catalog-api/src/app/catalog/entities/catalog-item.entity.ts (/Users/gperdomor/Developer/eshop/dist/apps/catalog-api/webpack:/apps/catalog-api/src/app/catalog/entities/catalog-item.entity.ts:29:10)
You need to reverse the order in the catalog-item.entity.ts file. Because the first class uses (references) the second one, which is declared later. So by the time of resolving it is not known..
@johannesschobel what do you mean? For now, i solved my issue creating a index.ts with this content
export * from './catalog-brand.entity';
export * from './catalog-type.entity';
export * from './catalog-item.entity';
and updating the import { CatalogItem } from './catalog-item.entity'; line of catalog-type.entity.ts and catalog-brand.entity.ts to import { CatalogItem } from './'
oh.. i am sorry @gperdomor , i misread your file-names.. i thought you would have 2 classes in the catalog-item.entity.ts file.. but its catalog-item and catalog-type. My bad.
Creating some kind of barrel-file (like you did) should work, yeah..
@johannesschobel聽yes, the problem in this case is the webpack bundle, because in a nest project, generated with nest new command, the original files works without problem
This fixed it for me:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { getMetadataArgsStorage } from 'typeorm';
import { typeOrmConfig } from '../config/typeorm.config';
@Module({
imports: [
...,
TypeOrmModule.forRoot({
...typeOrmConfig,
entities: getMetadataArgsStorage().tables.map(tbl => tbl.target)
})
]
})
export class AppModule {}
thank you very much, you save my days!
You need to reverse the order in the
catalog-item.entity.tsfile. Because the first class uses (references) the second one, which is declared later. So by the time of resolving it is not known..
They reference each-other so if you reverse their order then the other one will error out.
You could use strings instead of classes in this case, like so:
@OneToMany("Foo", "fooProp")
selectedRaeume: Foo[];
The type itself shouldn't matter as it's stripped away anyway.
Both TypeORM and MikroORM supports this, but MikroORM can also work without explicitly mentioning the class other than in the TS Type
My workaround works like this for run CLI command and connect entities from api code:
at the root folder I put a ormconfig.json for the CLI
{
"type": "mysql",
"host": "127.0.0.1",
"port": 9906,
"username": "root",
"password": "root",
"database": "test",
"synchronize": true,
"logging": false,
"entities": [
"libs/typeorm/src/lib/entity/**/*.ts"
],
"migrations": [
"libs/typeorm/src/lib/migration/**/*.ts"
],
"subscribers": [
"libs/typeorm/src/lib/subscriber/**/*.ts"
],
"cli": {
"entitiesDir": "libs/typeorm/src/lib/entity",
"migrationsDir": "libs/typeorm/src/lib/migration",
"subscribersDir": "libs/typeorm/src/lib/subscriber"
}
}
app.module.ts
TypeOrmModule.forRoot({`
"type": "mysql",
"host": environment.db.host,
"port": environment.db.port,
"username": environment.db.username,
"password": environment.db.password,
"database": environment.db.database,
"synchronize": true,
"autoLoadEntities": true
})
The really important here is you need to "overwrite" the values in app.module, if not the config from the ormconfig.json will not work. autoLoadEntities works like a charm here.
npm script to run typeorm CLI
"typeorm": "ts-node -P libs/typeorm/tsconfig.json ./node_modules/.bin/typeorm"
// ex: npm run typeorm migration:generate -- -n UserMigration
and finally the libs/typeorm/tsconfig.json
{
"compilerOptions": {
"types": ["node", "jest"],
"lib": [
"es5",
"es6"
],
"target": "es2015",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./build",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true
},
"include": ["**/*.ts"]
}
Works only with module commonjs
Hope this help.
Is there an elegant solution for this one that works for both ormconfig.js and typeorm migrations?
This fixed it for me:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { getMetadataArgsStorage } from 'typeorm';
import { typeOrmConfig } from '../config/typeorm.config';
@Module({
imports: [
...,
TypeOrmModule.forRoot({
...typeOrmConfig,
entities: getMetadataArgsStorage().tables.map(tbl => tbl.target)
})
]
})
export class AppModule {}

@r37r0m0d3l I tried it and getMetadataArgsStorage won't find the entities according to the glob pattern in production mode (bundle file generated with webpack)
The best solution I found for production build is to use https://docs.nestjs.com/techniques/database#auto-load-entities
autoLoadEntities do own job, but with getMetadataArgsStorage I don't have to write another dist path "dist/*/.entity{.ts,.js}" etc.
npm uninstall mysql
npm install --save mysql2
I found that inside generated dist/main.js file don't have any typeorm migration code.
How to load migrations file after build?
Should I tsc migration files and copy into dist folder?
In NestJS adding .js along side .ts worked for me
typeorm.config.ts
Before
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
export const TypeORMConfig: TypeOrmModuleOptions = {
type: 'postgres',
url: process.env.DATABASE_URL,
synchronize: true,
entities: [__dirname + '/../**/*.entity.ts'],
migrationsTableName: 'Migrations_History',
};
After
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
export const TypeORMConfig: TypeOrmModuleOptions = {
type: 'postgres',
url: process.env.DATABASE_URL,
synchronize: true,
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
migrationsTableName: 'Migrations_History',
};
I found that inside generated
dist/main.jsfile don't have any typeorm migration code.
How to load migrations file after build?Should I tsc migration files and copy into dist folder?
@kuccilim Im having same issue, did You fix it?
I found that inside generated
dist/main.jsfile don't have any typeorm migration code.
How to load migrations file after build?
Should I tsc migration files and copy into dist folder?@kuccilim Im having same issue, did You fix it?
I changed tsconfig to commonjs #1667, then manually run typeorm migrations.
typeorm migration:generate -n MigrationNametypeorm migration:run
Most helpful comment
This fixed it for me:
import { Module } from '@nestjs/common';import { TypeOrmModule } from '@nestjs/typeorm';import { getMetadataArgsStorage } from 'typeorm';import { typeOrmConfig } from '../config/typeorm.config';@Module({imports: [...,TypeOrmModule.forRoot({...typeOrmConfig,entities: getMetadataArgsStorage().tables.map(tbl => tbl.target)})]})export class AppModule {}