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

部署在Vercel的Express API中Swagger无法运行问题求助

问题:Express API部署到Vercel后/api-docs路由加载失败

错误信息

swagger-ui-bundle.js:3 未捕获的语法错误:意外的标记'<'(位于swagger-ui-bundle.js:3:1)
swagger-ui-standalone-preset.js:3 未捕获的语法错误:意外的标记'<'(位于swagger-ui-standalone-preset.js:3:1)
swagger-ui-init.js:658 未捕获的引用错误:SwaggerUIBundle未定义
在window.onload(swagger-ui-init.js:658:7)

问题描述

将Express API部署到Vercel生产环境后,访问/api-docs路由时出现上述错误。已尝试过customCssUrl相关的解决方案,但未解决问题,求可能的原因及修复方法。

相关代码

const express = require('express');
const app = express();
const routes = require('../routes.js');
const { connectDB } = require('../config/database-config.js');
const errorHandler = require('./middlewares/error-middleware.js');
const { readEnvironmentFile } = require('../config/envFile.js');
const getFixturesCronJob = require('./jobs/get_fixtures_cron_job.js');
const calculateSuccessRateCronJob = require('./jobs/calculate_success_rate_cron_job.js');
const { swaggerUi } = require('../config/swagger-config.js');

const path = require('path');
const YAML = require('yamljs');

const swaggerFilePath = path.resolve(__dirname, './swagger.yaml');
const swaggerDocument = YAML.load(swaggerFilePath);
readEnvironmentFile();
connectDB();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

app.use(routes);
app.use(errorHandler);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));

app.listen(7600, () => {
  console.log(`Server started on port ${7600}`);
  getFixturesCronJob.start();
  calculateSuccessRateCronJob.start();
});

module.exports = app;

解决方案

这些错误的核心原因是Swagger UI依赖的静态JS文件(swagger-ui-bundle.js等)未被正确加载,反而返回了HTML内容(比如404错误页面),导致浏览器解析JS时遇到<语法错误,进而引发SwaggerUIBundle未定义的问题。针对Vercel部署场景,主要排查以下几点:

1. 调整中间件顺序

你的代码里errorHandler放在了/api-docs路由之前,当Swagger的静态资源请求进来时,若路由匹配失败会直接被错误处理中间件拦截并返回HTML错误页面。把/api-docs路由移到errorHandler之前:

// 先挂载api-docs路由
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
// 再挂载错误处理中间件
app.use(errorHandler);

2. 显式指定Swagger静态资源服务

替换swaggerUi.serve为swaggerUi.serveFiles,确保静态资源能被正确映射:

app.use('/api-docs', swaggerUi.serveFiles(swaggerDocument), swaggerUi.setup(swaggerDocument));

3. 配置Vercel的路由规则

在项目根目录创建vercel.json,添加路由重写规则,确保Swagger的静态资源请求被正确转发到Express应用:

{
  "rewrites": [
    { "source": "/api-docs/(.*)", "destination": "/api-docs/$1" },
    { "source": "/(.*)", "destination": "/server.js" } // 替换为你的Express入口文件名
  ]
}

4. 检查依赖部署情况

确认Vercel构建时没有忽略swagger-ui-express的静态资源。可以在构建日志里搜索swagger-ui-bundle.js,确认这些文件是否被包含在部署包中。如果缺失,尝试在package.json里添加vercel-build脚本,确保依赖被完整安装:

{
  "scripts": {
    "vercel-build": "npm install && npm run build" // 按需调整build命令
  }
}

内容的提问来源于stack exchange,提问作者Petar Dzhunov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:02:31