You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Webpack忽略指定模块?兼顾前后端共享代码的文档功能

解决Next.js前端构建时忽略@nestjs/swagger以减小体积的方案

刚好处理过类似的前后端共享DTO代码的场景——既要保留后端的Swagger文档能力,又要在Next.js前端构建时把@nestjs/swagger相关代码完全剔除来压缩包体积,这里有几个靠谱的方案:

方案1:环境变量+空装饰器兜底

利用环境变量区分前后端环境,只在后端(Node.js环境)下加载@nestjs/swagger的装饰器,前端环境下用空函数替代,这样既不影响类型提示,也不会引入无用模块。

修改你的DTO代码如下:

// 根据环境决定是否加载真实的ApiProperty装饰器
const ApiProperty = process.env.NODE_ENV !== 'browser' 
  ? require('@nestjs/swagger').ApiProperty 
  : () => () => {};

export class AccessTokenResponseDto {
  @ApiProperty({ example: 'xxxxx.xxxxx.xxxxx' })
  public token!: string;
}

小提示:如果用TypeScript,为了避免process的类型报错,可以在项目的types目录下加个声明文件,或者直接在当前文件顶部临时声明:

declare const process: {
  env: {
    NODE_ENV: string;
  };
};

这种方案的好处是不用额外加依赖,代码改动也很小,前端构建时会自动忽略@nestjs/swagger的导入。

方案2:用Babel插件自动清理无用代码

如果不想改动业务代码,用Babel插件在构建阶段自动移除@nestjs/swagger的导入和相关装饰器是更省心的选择。

操作步骤:

  1. 安装所需插件:
npm install babel-plugin-transform-remove-imports babel-plugin-remove-decorators --save-dev
  1. 在Next.js的Babel配置文件(.babelrc或者babel.config.js)里添加配置:
module.exports = {
  presets: ['next/babel'],
  plugins: [
    // 移除所有@nestjs/swagger的导入语句
    [
      'babel-plugin-transform-remove-imports',
      {
        test: '@nestjs/swagger',
      },
    ],
    // 移除所有@ApiProperty装饰器
    [
      'babel-plugin-remove-decorators',
      {
        decoratorsBeforeExport: true,
        remove: ['ApiProperty'],
      },
    ],
  ],
};

这样配置后,Next.js在构建前端代码时,会自动把所有和@nestjs/swagger相关的导入、装饰器都清理掉,完全不会留在最终的打包文件里。

方案3:拆分DTO(基础版+后端扩展版)

如果上面两种方案都不符合你的需求,也可以把DTO拆成两个版本:

  • 一个基础DTO:只包含属性定义,不带任何装饰器,供前后端共享。
  • 一个后端DTO:继承基础DTO,加上@ApiProperty装饰器,只在后端使用。

示例代码:

// 共享的基础DTO(shared/dtos/access-token.base.dto.ts)
export class AccessTokenResponseBaseDto {
  public token!: string;
}

// 后端专用DTO(backend/dtos/access-token.response.dto.ts)
import { ApiProperty } from '@nestjs/swagger';
import { AccessTokenResponseBaseDto } from '../../shared/dtos/access-token.base.dto';

export class AccessTokenResponseDto extends AccessTokenResponseBaseDto {
  @ApiProperty({ example: 'xxxxx.xxxxx.xxxxx' })
  public token!: string;
}

// 前端直接导入基础DTO
import { AccessTokenResponseBaseDto } from '../shared/dtos/access-token.base.dto';

这种方式完全隔离了前后端的DTO代码,前端不会接触到任何Swagger相关内容,但缺点是属性变更时需要同步修改两个文件,维护成本稍高。

个人推荐优先选方案2,自动化程度高还不侵入业务代码;如果不想加依赖的话,方案1也是个不错的选择。

内容的提问来源于stack exchange,提问作者Eric Goerens

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 17:52:53