部署Next.js API到Vercel时如何避免依赖包CSS被移除?
解决Next.js API中访问swagger-ui-dist CSS被Tree Shaking移除的问题
先纠正一个误解
Tree Shaking不是由Vercel执行的,它是Webpack(Next.js默认的打包工具)在本地构建或Vercel构建阶段完成的代码优化操作,Vercel仅负责部署构建后的产物,不参与Tree Shaking的执行环节。
可行的解决方法
方法1:直接在API路由中读取CSS文件(最可靠)
API路由运行在Node.js环境,完全可以跳过Webpack打包流程,直接用Node.js文件系统模块读取node_modules里的CSS文件:
// pages/api/swagger-css.js import fs from 'fs'; import path from 'path'; export default function handler(req, res) { // 拼接swagger-ui.css的绝对路径 const cssFilePath = path.join(process.cwd(), 'node_modules', 'swagger-ui-dist', 'swagger-ui.css'); try { const cssContent = fs.readFileSync(cssFilePath, 'utf8'); res.setHeader('Content-Type', 'text/css'); res.status(200).send(cssContent); } catch (err) { res.status(500).send('Failed to load Swagger UI CSS'); } }
之后在Swagger文档页面直接调用这个API获取CSS即可,完全不受Tree Shaking影响。
方法2:修正Webpack的sideEffects配置
如果一定要通过Webpack打包保留CSS,需要确保配置正确标记swagger-ui-dist的CSS为有副作用:
修改next.config.js:
/** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config) => { // 让Webpack不对swagger-ui-dist的CSS做Tree Shaking config.module.rules.forEach(rule => { if (rule.oneOf) { rule.oneOf.forEach(oneOfRule => { if (oneOfRule.test?.test('.css')) { oneOfRule.exclude = [...(oneOfRule.exclude || []), /swagger-ui-dist/]; } }); } }); // 确保sideEffects优化开启,同时正确识别包内的副作用文件 config.optimization.sideEffects = true; return config; }, }; module.exports = nextConfig;
同时在项目根目录的package.json中补充sideEffects声明:
{ "sideEffects": [ "node_modules/swagger-ui-dist/*.css" ] }
这种方式需要确保Webpack配置没有被其他规则覆盖,相对来说不如方法1直接。
内容的提问来源于stack exchange,提问作者Federico Peralta
相关产品推荐
相关产品推荐

