Dynamic Modules
To create a dynamic module we have two approaches:
First Approach
- AKA manual implementation.
- Needs a lot of boilerplate codes.
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
- A better way.
- My personal preference.
- Use
ConfigurableModuleBuilder. - Learn more about it in the official documentation.
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'); }