NestJS materials

Write an awesome doc for NestJS tips, tricks, notes, things which are not in the doc (or are but not really obvious) and experimented to figure them out and use them.

View on GitHub

Dynamic Modules

To create a dynamic module we have two approaches:

First Approach

ManualModule.register({
  global: true,
  someOption: 123,
})

ManualModule.registerAsync({
  global: true,
  useFactory() {
    return {
      someOption: 123,
    }
  },
})

class ManualModuleOptions implements ManualModuleOptionsFactory {
  create() {
    return {
      someOption: 123,
    }
  }
}

ManualModule.registerAsync({
  global: true,
  useClass: ManualModuleOptions,
})

Seconds Approach

MyModule.register({
  global: true,
  someOption: 123,
  myExtra: 'extra-register',
})

MyModule.registerAsync({
  global: true,
  myExtra: 'extra-register-async-useFactory',
  useFactory() {
    return {
      someOption: 123,
    }
  },
})

class MyModuleOptions implements MyModuleOptionsFactory {
  create() {
    return {
      someOption: 123,
    }
  }
}

MyModule.registerAsync({
  global: true,
  myExtra: 'extra-register-async-useClass',
  useClass: MyModuleOptions,
})

[!NOTE]

  • If you need to be able to inject extra options you need to define a new provider which provides exactly the extra options.
  • NestJS’s ConfigurableModuleBuilder.setExtras() has a design limitation, it requires you to provide default values for ALL properties in the extras type, which makes them all effectively optional from TypeScript’s perspective. So we need to make sure at runtime that we got all mandatory extra options:
    if (!myExtra) {
      throw new Error('myExtra is required in MyModule options');
    }
    

More examples