Search code examples
javascriptreactjsnestjsmonoreponestjs-swagger

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


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?


Solution

  • 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