【NestJS】构建可复用的数据存储模块 - 动态模块

动态模块

Nest 中的动态模块允许你创建可在运行时配置的模块,而不是使用静态的固定配置。当你需要提供灵活、可定制的模块时,这尤其有用。


使用场景

在项目中有用户(UserModule)、书籍(BookModule)等模块,我希望通过 json 文件来存储对应模块数据。 这个时候就可以定义一个存储模块(DbModule),用来定义存储的读取和写入方法,其他模块在使用存储模块时,传入 json 文件路径。

在 UserModule 里用的时候,path 是 users.json,在 BookModule 用的时候,path 是 books.json。

这个 DbModule 就是动态模块


创建动态模块

1. 定义动态模块

ts 复制代码
import { DynamicModule, Module } from '@nestjs/common';
import { DbService } from './db.service';
​
export interface DbModuleOptions {
  path: string
}
​
@Module({})
export class DbModule {
  static register(options: DbModuleOptions): DynamicModule {
    return {
      module: DbModule,
      providers: [
        {
          provide: "OPTIONS",
          useValue: options
        },
        DbService,
      ],
      exports: [DbService]
    }
  }
}

该方法返回一个 DynamicModule 对象,包含以下属性:

  • module: 指定这个动态模块对应的类

  • providers: 定义该模块提供的服务

    • 把传入的 options 用 useValue 来声明为 provider;token 为 OPTIONS。

      记住 provide 定义的值,后面要考(会用到)

    • DbService 中实现读取和写入方法

  • exports: 指定哪些服务可以被导入该模块的其他模块使用

2. 定义动态模块对应的 service

service 中实现读取和写入方法,注入

ts 复制代码
import { Inject, Injectable } from '@nestjs/common';
import { DbModuleOptions } from './db.module';
import { access, readFile, writeFile } from 'fs/promises';
​
@Injectable()
export class DbService {
  @Inject('OPTIONS')
  private options: DbModuleOptions;
​
  // 读取
  async read() {
    const filePath = this.options.path;
    // 读取文件内容
    const str = await readFile(filePath, { encoding: 'utf-8' });
    // 转为对象
    return JSON.parse(str);
  }
​
  // 写入
  async write(obj: Record<string, any>) {
    await writeFile(this.options.path, JSON.stringify(obj || []), {
      encoding: 'utf-8',
    });
  }
}
​

使用动态模块

在 UserModule 中使用

ts 复制代码
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { DbModule } from 'src/db/db.module';
​
@Module({
  imports: [
    DbModule.register({
      path: 'users.json',
    }),
  ],
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}
​

在 UserService 中使用就和静态模块一样了

js 复制代码
import { Inject, Injectable } from '@nestjs/common';
import { DbService } from '../db/db.service';
import { User } from './entities/user.entity';
​
@Injectable()
export class UserService {
  @Inject(DbService)
  dbService: DbService;
​
  async register() {
    // 读取
    const users = await this.dbService.read();
​
    // ...
​
    // 写入
    await this.dbService.write(user)
    return user
  }
}
相关推荐
QQ1__8115175155 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态5 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子5 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室5 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI5 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing5 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者5 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册5 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李5 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢5 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web