
document.querySelector('.swagger-ui') === null 说明 Swagger-UI 的容器 DOM 还没被创建,常见缘由只有三类:
- HTML 文件里根本就没写 <div>
- 写了,但 swagger-ui-bundle.js 加载失败或被 CORS 拦掉,导致脚本没跑
- 脚本跑了,但你把 .html 放进了 asar 打包,file:// 协议下 Chrome 禁止加载 asar 内的 .js,于是 bundle 404,页面空白
下面按「肉眼可见 → 控制台 → 协议问题」三步 2 分钟定位。
一、肉眼可见:先把页面停住看一眼
const browser = await puppeteer.launch({ headless: false, devtools: true });
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle0' });
await page.waitForTimeout(5000); // 停 5 s 给你看
- 窗口里有没有出现绿色横幅 「Swagger UI」?
- 没有 → 继续第二步;有 → 等渲染完再查 DOM(跳第三步)
二、控制台查两项
在 DevTools 里立刻执行:
- 网络面板
看看 swagger-ui-bundle.js 是不是 404(红字) 如果是 404,几乎肯定你把
node_modules/swagger-ui-dist 打进了 asar,而 file:// 协议禁止读 asar 内的 JS。
- 控制台报错
“ Failed to load resource: net::ERR_FILE_NOT_FOUND “
或 CORS 提示 → 都是同源策略拦掉。
三、根因与对应修复
|
场景 |
现象 |
修复 |
|
asar 内引 js 404 |
网络面板 404 |
把 swagger-ui-dist 设为 externals 不打包,或复制到 resources 文件夹,用绝对 file:// 路径 |
|
路径写错 |
404 路径明显不对 |
打印 |
|
没写容器 div |
Elements 里只有 “ |
确保 HTML 里有 “ |
|
脚本顺序错 |
控制台出现 SwaggerUIBundle is not defined |
先引 bundle.js,再执行内联脚本 |
四、最小可工作 HTML(asar 外路径示例)
import swaggerUiDist from 'swagger-ui-dist';
import path from 'path';
const SWAGGER_ASSETS = swaggerUiDist.getAbsoluteFSPath(); // ① 真实目录
const htmlOut = path.join(outDir, 'swagger.html');
const html = `
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Swagger</title>
<link rel="stylesheet" href="${SWAGGER_ASSETS}/swagger-ui.css"/>
</head>
<body>
<div id="swagger-ui"></div> <!-- ② 容器必定要有 -->
<script src="${SWAGGER_ASSETS}/swagger-ui-bundle.js"></script>
<script>
SwaggerUIBundle({
spec: ${JSON.stringify(swaggerJson)}, // ③ 内联 JSON,避免 fetch
dom_id: "#swagger-ui"
});
</script>
</body>
</html>`;
fs.writeFileSync(htmlOut, html);
五、electron-builder 不打包方案(推荐)
electron.vite.config.ts
export default defineConfig({
main: {
build: {
rollupOptions: {
external: ['swagger-ui-dist'] // 不 bundle
}
}
},
...
})
把资源复制到 resources:
// electron-builder.yml
extraResources:
- from: node_modules/swagger-ui-dist
to: swagger-ui-dist
HTML 里路径改成:
<link rel="stylesheet" href="../swagger-ui-dist/swagger-ui.css"/>
<script src="../swagger-ui-dist/swagger-ui-bundle.js"></script>
这样 file:// 协议也能正常加载,不会再 404。
六、再测一次
await page.goto(url, { waitUntil: 'networkidle0' });
await page.waitForSelector('#swagger-ui .info', { timeout: 10000 }); // 等标题出现
console.log(await page.$eval('#swagger-ui', el => el.innerText.slice(0, 50)));
能打印出 「Swagger UI」 字样就说明 DOM 已生成,后面再 .opblock 就不会 null。
30 秒复盘
- 开 headless: false → 看有没有绿色横幅。
- 网络面板若 404 → 把 swagger-ui-dist 放 resources 并改路径。
- 保证 HTML 里 有容器 div、bundle.js 能加载、JSON 内联。
三步做完 document.querySelector('.swagger-ui') 必不为 null,祝调试顺利!

