#Share TypeORM entities and services across multiple NestJS apps via a private library

12 messages · Page 1 of 1 (latest)

vestal rock
#

I'm trying to build a shared private library to reuse TypeORM entities and some common services across multiple NestJS applications without duplicating code.

For simplicity, let's say my shared library is called pets-lib. It’s a NestJS app without a main.ts file, and it exports modules, services, and entities.

In pets-lib, I have a module and service set up like this:

cats.module.ts

`import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Cat } from '../entities';

@Module({
imports: [TypeOrmModule.forFeature([Cat])],
providers: [CatService],
exports: [CatService],
})
export class CatsModule {}`

cats.service.ts

`import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Cat } from '../entities';
import { Repository } from 'typeorm';

@Injectable()
export class CatsService {
constructor(
@InjectRepository(Cat)
private readonly catsRepository: Repository<Cat>,
) {}
}`

Then in my main NestJS app, I import the shared module like this:

app.module.ts

`import { Cat, CatsModule } from 'pets-lib';
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: () => ({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'pets',
entities: [Cat],
synchronize: false,
}),
}),
CatsModule
],
controllers: [],
})
export class AppModule {}`

However I get the following error:

Error: Nest can't resolve dependencies of the CatsRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule

How can I solve this problem?
Any help would be appreciated!

scarlet gull
#

Try putting the TypeORM module in the exports of your CatsModule.

@Module({
  imports: [
    TypeOrmModule.forFeature([Cat]),
  ],
  providers: [CatsService], 
  exports: [
    TypeOrmModule, // Export TypeOrmModule to make its providers (including repositories) available
    CatsService, 
  ],
})
export class CatsModule {}
vestal rock
# scarlet gull Try putting the TypeORM module in the exports of your CatsModule. ```ts @Modu...

I tried it, but it didn't work. I made a sample if it makes it easier to debug. It would probably be better to structure this in a monorepo, but currently I cannot migrate all my apps to a single monorepo project.

The pets-lib project is basically a private library that I want to publish, which will be installed by multiple other apps

To test this, first build the library:

cd pets-lib
pnpm i
pnpm build (after each change in the pets-lib)

cd ..

cd pets-app
pnpm i
pnpm start:dev

The pets-lib is referenced in package.json like this:
"pets-lib": "link:..\\pets-lib",

I can publish this to github if needed

scarlet gull
#

Maybe a dumb question, but after making the change, did you rebuild your library?

I see you have peer deps, but you probably also need the TypeORM dependencies in peer deps. Something along the lines of:

{
 ...
 "peerDependencies": {
   "@nestjs/common": "^10.0.0",
   "@nestjs/core": "^10.0.0",
   "@nestjs/platform-express": "^10.0.0",
   "reflect-metadata": "^0.2.0",
   "rxjs": "^7.8.1",
   "@nestjs/typeorm": "^10.0.0",
   "typeorm": "^0.3.0"
 },
 "dependencies": {
   // other dependencies specific to your library's implementation
 }
 // ...
}

If this is going to be the future status quo for your app development, you will definitely be better off in a monorepo using pnpm's workspace feature. 🙂

amber pike
#

Nx also allow package sharing without the pain of maintaining a library with versions

vestal rock
# scarlet gull Maybe a dumb question, but after making the change, did you rebuild your library...

This specific use case happens in the company I work, and the architecture used for a long time is polyrepo.

In the most recent developments, we started using a monorepo approach, with turborepo to integrate multiple apps, and it works very well.

I think the problem would still be the same. I wouldn't be able to import the module into another apps.

This problem is specific to typeorm, I have another module that I export that depends on an HttpModule and I can import it in any app I want.

I did the following to try your suggestion, still didn't work 😦

  • updated the peerDependencies in pets-lib package.json
  • removed node_modules from pets-lib and pets-app
  • installed the dependencies on pets-lib
  • rebuilded pets-lib
  • installed the dependencies on pets-app
  • started pets-app

Were you able to start the pets-app application after the changes you suggested?

scarlet gull
#

I didn't try. If you could, it would be easier for me to take a look, if you could create a github repo to clone from.

vestal rock
scarlet gull
vestal rock
scarlet gull
#

That‘s the beauty of pnpm workspaces, it models how the package would be pulled in from npm. You could swap out the workspace:* for the published version and it will work.

vestal rock