typeorm: code minify causes "Entity metadata for e#activities was not found"

Issue type:

[ ] question [x] bug report [ ] feature request [ ] documentation issue

Database system/driver:

[ ] cordova [ ] mongodb [ ] mssql [ ] mysql / mariadb [ ] oracle [ ] postgres [ ] cockroachdb [x] sqlite [ ] sqljs [ ] react-native [ ] expo

TypeORM version:

[ ] latest [ ] @next [x ] 0.2.18

Steps to reproduce or a small repository showing the problem:

@Entity('space')
export default class Space {
  @PrimaryColumn()
  spaceId: string;

  @Column()
  spaceName: string;

  @OneToMany('activity', 'space')
  activities: Promise<Activity[]>
}

@Entity('activity')
export default class Activity {
  @PrimaryColumn()
  activityId: string;

  @Column('text')
  text: string;

  @ManyToOne('space', 'activities')
  @JoinColumn({ name: 'spaceId' })
  space: Promise<Space>
}

In my project, code minifing (uglifyjs) is required, it will convert classnames like ‘Space’ into single characters like ‘e’. The problem occurs here in EntityMetadataBuilder.ts:L649.

IMHO m.givenTableName is not honored but should. Therefore we can use uglifyjs without breaking typeorm.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 2
  • Comments: 22 (6 by maintainers)

Commits related to this issue

Most upvoted comments

My Solution

Just declare unique static property name for each of your classes image

How does this fix the “Cyclic dependency” error of minified code?

This error derives from function SubjectTopoligicalSorter.toposort() which requires unique targetNames. Those targetNames are extracted from the special property Function.name of our classes (yes, classes are functions in JS). However, after the minification process, the class names (function names) are changed to something like “t”, “e”,… which can be duplicated. Therefore, manually assign unique name values for our classes solved the problem.

Bonus Solution

You can configure the bundler not to touch the function names to fix this. However, I personally don’t prefer this method. Take my metro.config.js file for example (I’m using typeorm in React Native project)

module.exports = {
  transformer: {
    minifierConfig: {
      keep_fnames: true, // To avoid cyclic dependency "t" error of typeorm in release build
    },
  },
};

Hey,

hope i am not late to the party. We had this issue with optimization ( minify ) in Ionic too.

To solve the problem you have to

  1. Add a name to the entity
  2. Use that name instead of the ObjectType itself in getRepository() and on any relation such as ManyToOne or ManyToMany

Entity:

@Entity('table') export class Table { @PrimaryGeneratedColumn() id!: number; @OneToOne('second_table', { cascade: ['insert', 'update'] }) };

@Entity('second_table') export class SecondTable { @PrimaryGeneratedColumn() id!: number; };

get Repository:

this.tableRepository = this.sqliteService.getDataSource().getRepository('table');

You can use the Entities in the declaration of your Datasource entities array.

const db = new DataSource({ name: 'ionic--app', type: 'capacitor', driver: sqliteConnection, database: 'ionic-sqlite', mode: 'no-encryption', entities: [ Table, SecondTable ], migrations: [], subscribers: [], logging: ['error', 'schema'], synchronize: false, migrationsRun: false, });

Hope that helps.

Hello guys, I spent a week trying to solve a problem like this. So I solved this problem, just changed my repository method that saves the entity. I used repository.save (entity) and always failed with cyclic dependency.

After switching to

repository.createQueryBuilder()
    .insert()
    .into(TABLE_NAME)
    .values(entity)
    .execute();

This error has been cleared. I really recommend trying to change the repository method, because the save() method waits for the full entity set and createQueryBuilder() takes the entity values and turns them into string values, making a normal query.

I was using serverless and webpack. Typeorm does not work well with webpack.

@cvdat2097 Dude you are a hero. 🚀 🚀

@chriswep you can try to use custom names for entities and column names, it might work, but you need to check it.

I checked, i already use custom names for all entities. Not for column names though. However if i exclude the entity classes from terser mangle then it works, so i think the only issue is with typeorm still using the classname somewhere.

@GeorgeZhangZHY wrote above that the issue might be related to relations:

Well, I gave up using @ManyToOne/@OneToMany. The @Entity(‘entity_name’) works with code minifying, but the relation decorators do not.

@GeorgeZhangZHY i figured out a way to make TypeORM work without skiping the minifying process of the PROD build.

You have to declare your entities using the EntitySchema definition, which can be found here: https://typeorm.io/#/separating-entity-definition

The only problem with this approach is that typeORM loses some of its type completion, but you can overcome this by creating interfaces for the schemas you define. I was able to run ‘ionic cordova build android --prod’ without issues.

Hope this helps you.

@barretojs Well, I gave up using @ManyToOne/@OneToMany. The @Entity('entity_name') works with code minifying, but the relation decorators do not.