部署在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
相关产品推荐
相关产品推荐

