如何用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的导入和相关装饰器是更省心的选择。
操作步骤:
- 安装所需插件:
npm install babel-plugin-transform-remove-imports babel-plugin-remove-decorators --save-dev
- 在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
相关产品推荐
相关产品推荐

