How to use NX DTO libraries decorated with NestJS swagger api in frontend frameworks

694 Views Asked by At

I have a nestjs dto in my NX project library declared like following:

import { ApiProperty } from '@nestjs/swagger';
import { MinLength, MaxLength, IsNotEmpty, IsEmail } from 'class-validator';

class SignInDto {

    @ApiProperty({
        example: '[email protected]',
    })
    @IsEmail()
    @IsNotEmpty()
    username: string;

    @ApiProperty({
        example: 'password',
    })
    @MinLength(8)
    @MaxLength(64)
    @IsNotEmpty()
    password: string;
}

export { SignInDto };

And I also want to use the same dto and class validator properties for frontend form validation in react something like:

import { SignInDto } from '@project/dto';

const SignIn = () => {

    ...

    const {
        register,
        handleSubmit,
        formState: { errors },
    } = useForm<SignInDto>({
        resolver: classValidatorResolver(SignInDto),
    });

    ...
    
}

But it will result in error like the following denoting it can't resolve node module

WARNING in ../../node_modules/@nestjs/common/utils/load-package.util.js 9:39-59
Critical dependency: the request of a dependency is an expression

WARNING in ../../node_modules/@nestjs/core/helpers/load-adapter.js 9:39-63
Critical dependency: the request of a dependency is an expression

WARNING in ../../node_modules/@nestjs/core/helpers/optional-require.js 6:39-59
Critical dependency: the request of a dependency is an expression

WARNING in ../../node_modules/@nestjs/microservices/client/client-grpc.js 28:14-34
Critical dependency: the request of a dependency is an expression

WARNING in ../../node_modules/@nestjs/microservices/server/server-grpc.js 25:14-34
Critical dependency: the request of a dependency is an expression

WARNING in ../../node_modules/engine.io/node_modules/ws/lib/buffer-util.js 103:21-42
Module not found: Error: Can't resolve 'bufferutil' in '/home/noman1001/Projects/rentigo/node_modules/engine.io/node_modules/ws/lib'

WARNING in ../../node_modules/engine.io/node_modules/ws/lib/validation.js 109:22-47
Module not found: Error: Can't resolve 'utf-8-validate' in '/home/noman1001/Projects/rentigo/node_modules/engine.io/node_modules/ws/lib'

WARNING in ../../node_modules/express/lib/view.js 81:13-25
Critical dependency: the request of a dependency is an expression

WARNING in ../../node_modules/on-finished/index.js 207:11-33
Module not found: Error: Can't resolve 'async_hooks' in '/home/noman1001/Projects/rentigo/node_modules/on-finished'

WARNING in ../../node_modules/raw-body/index.js 302:11-33
Module not found: Error: Can't resolve 'async_hooks' in '/home/noman1001/Projects/rentigo/node_modules/raw-body'

....
....
....

the list goes on

How do I keep using my DTOs and swagger documentation intact?

1

There are 1 best solutions below

0
On BEST ANSWER

I traced the bug to ApiProperty and import of '@nestjs/swagger' modules.

Whenever I eliminate the Swagger docs from the DTO it just compiles fine.

So to keep my swagger docs and compiling my frontend at the same time, I wrote a webpack loader that just removes the decorators associated with nestjs/swagger

module.exports = (source) => {
  const regex = /@ApiProperty\((.|\s)*?\)/gm;
  const subst = '';
  const result = source.replace(regex, subst);
  return result;
};

and used the plugin in my webpack config in the frontend react project

const path = require('path');
const { merge } = require('webpack-merge');

module.exports = (config, context) => merge(config, {
  // use ./loaders/dto-adapter.loader.js
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: path.resolve(__dirname, './loaders/dto-adapter.loader.js'),
        exclude: /node_modules/,
      },
    ],
  },
});

This could be extended to eliminate other API decorators from swagger

And now the frontend compiles just fine

EDIT: I initially tried with babel plugins, but they are just not performing reliably all the time