0

我在使用Nx的 monorepo 设置中使用NestJs,NextJs 作为客户端。我的基本架构是拥有包含特定域(身份验证、用户、帖子等)的所有逻辑(客户端、服务器和 api 代码)的模块,然后拥有这些模块使用的服务(CssService、DbService、JwtService、ValidationService 等) . 文件夹结构看起来像这样(我已经为这个演示删除了不必要的桶/Nx lib 文件):

modules
  auth
    api
      signup
        client
          service-methods-and-properties
            signup.error-messages.ts
            signup.fields.ts
            signup.form.logic.ts
            signup.form.ui.tsx
            signup.form.tsx
            signup.mutation.generated.ts
            signup.mutation.gql
          signup.service.ts
          signup.types.ts

        server
          service-methods-and-properties
            signup.input.ts
            signup.logic.ts
            signup.response.ts
          signup.service.ts
          signup.types.ts

    client
      pages
        signup
          signup.page.tsx

    server
      auth.module.ts
      auth.resolver.ts

services
  db
    client
      db.service
    server
      db.service

在我的 NestJs 身份验证解析器 (modules/auth/server/auth.resolver) 中,我导入 SignupServerService 以供注册处理程序使用:

import { SignupServerService } from '../api/signup/server';

@Resolver()
export class AuthResolver {
  constructor(private readonly signupServerService: SignupServerService) {}

  @Mutation(() => SignupServerService.Response)
  async signup(
    @Args('input') input: SignupServerService.Input
  ): Promise<typeof SignupServerService.Response.prototype> {
    return this.signupServerService.logic(input);
  }

}

这是注册服务器服务:

@Injectable()
export class SignupServerService {
  constructor(
    private readonly gqlServerService: GqlServerService,
    protected readonly dbServerService: DbServerService,
    protected readonly jwtServerService: JwtServerService
  ) {}

  static readonly Input = SignupInput;

  static readonly Response = SignupResponse;

  readonly logic = signupLogic;
}

但是,这有几个问题,我有一些相关的问题:

  1. 该代码有效,但我在我的 resolver 中得到了这行的几个 TS 错误,如果我直接从文件中@Args('input') input: SignupServerService.Input使用它就会消失,而不是通过类静态访问它。错误是和SignupInputsignup.input.tsSignupServerService'SignupServerService' only refers to a type, but is being used as a namespace here.ts(2702)Parameter 'input' of public method from exported class has or is using private name 'SignupServerService'.ts(4073)

  2. 支持问题 1,我在 上使用了一些静态属性,SignupServerService因此我可以传递SignupServerService.Response@Mutation装饰器 args,因为以下内容不起作用@Mutation(() => this.signupServerService.Response)。我想知道为什么这不起作用?我使用静态方法将属性传递给装饰器参数的模式是最好的方法吗?我应该使用 TS 命名空间而不是静态类方法还是有更好的方法来处理这个?

  3. 此外,我听说静态方法会导致单元测试出现问题,应该避免吗?NestJs 文档的日志记录部分提到了这一点,但还不足以得出任何结论:“这种技术虽然简单,但并未对 MyLogger 类使用依赖注入。这可能会带来一些挑战,尤其是对于测试,并限制 MyLogger 的可重用性”

  4. 这让我想到了一个关于在 monorepo 中使用 NestJs 的更普遍的问题。我经常需要在一些 NestJs 代码和一些 React 代码之间共享一个类/服务(例如我的自定义 JwtService - 注意,这不是 NestJs 内置的 JwtService)。自然,功能性反应组件不使用 DI 系统,因此要访问 JwtService 上的属性,我需要将它们设为静态(例如JwtService.ACCESS_TOKEN_COOKIE_NAME),这意味着在 JwtService 类中复制属性(例如static ACCESS_TOKEN_COOKIE_NAME = ACCESS_TOKEN_COOKIE_NAME; ACCESS_TOKEN_COOKIE_NAME = ACCESS_TOKEN_COOKIE_NAME),或者不要使用静态方法并在我的反应代码中手动实例化服务(例如const { ACCESS_TOKEN_COOKIE_NAME } = new JwtService())。但是,如果服务具有我必须手动提供给类构造函数参数的依赖项,则这将变得不可用,特别是如果依赖项仅由 NestJs 代码中使用的方法使用(例如const { ACCESS_TOKEN_COOKIE_NAME } = new JwtService(new SomeDependencyNotNeededForReact()))。那么在这种情况下最好的解决方案是什么?

4

0 回答 0