Pascal Editor 是一个基于 WebGPU 的 3D 编辑器项目,官方推荐用 Bun 作为运行时和包管理器来启动。我第一次接触它的时候,本地 bun dev 跑得挺顺,浏览器里能正常拖拽模型、切视角。但只要把它放到公网地址上访问,页面要么白屏,要么控制台直接报错。
这篇文章把两段过程分开写:先把本地跑通,再说公网访问为什么报错、我是怎么定位的。涉及具体命令和配置文件我都会写清楚,但凡是我不确定的地方会直接标出来,不会硬编一个答案糊弄过去。
先搞清楚 Pascal Editor 是什么
Pascal Editor 是一个运行在浏览器里的 3D 编辑器,渲染层依赖 WebGPU。它不是那种把模型传到服务端再返回图片的架构,而是把几何数据、场景图都放在前端,用 GPU 直接渲染。这一点决定了后面公网访问的问题性质------它不是一个纯静态页面,也不是一个普通的 REST 后端。
Bun 在这里承担两个角色:一是作为包管理器(bun install),二是作为开发服务器和脚本运行时(bun dev / bun run)。相比 Node + npm,Bun 启动 dev server 的速度确实快一些,冷启动基本在一秒内,这一点在反复改代码、重启服务的时候体感明显。
需要提醒的是,Pascal Editor 的具体版本迭代比较快,我写这篇文章时用的是仓库当时的主分支。如果你拉下来的版本和我不同,命令或目录结构可能有差异,以仓库里的 README 和 package.json 为准。
环境准备:Bun 的安装与校验
我用的系统是 macOS,Linux 下步骤基本一致,Windows 建议用 WSL。
安装 Bun 的官方命令是:
bash
curl -fsSL https://bun.sh/install | bash
装完之后确认版本:
bash
bun --version
我本地当时是 1.1.x 这个区间。这里我不写死具体小版本号,因为 Bun 更新很频繁,写死了反而容易误导。你只要保证是一个比较新的版本即可,太老的版本可能在 WebGPU 相关的依赖解析上有问题。
【注意】Bun 的安装脚本会往 shell 配置里写 PATH。装完如果 bun --version 提示找不到命令,先 source ~/.zshrc 或重开一个终端,不要急着重装。
拉代码、装依赖、跑起来
克隆仓库之后进目录:
bash
git clone <Pascal Editor 仓库地址>
cd pascal-editor
bun install
bun install 会读 package.json 和 bun.lockb(或 bun.lock,取决于版本),速度比 npm 快不少。如果这一步卡在某个原生依赖上,先看它是不是需要编译工具链。
依赖装完启动开发服务器:
bash
bun dev
终端一般会打印出类似 http://localhost:5173 的地址(端口以实际输出为准,很多基于 Vite 的项目默认 5173)。用 Chrome 打开这个地址,如果能看到编辑器界面、能加载模型,说明本地这一环就通了。
这里有个前提:WebGPU 目前主要在较新的 Chromium 内核浏览器里默认可用 。Chrome 113 之后逐步开放,但不同平台、不同版本开关状态不一样。如果本地就白屏,先在浏览器地址栏进 chrome://gpu,看 WebGPU 那一项是不是被标成 disabled。这一点我建议你亲自确认,因为各人机器差异很大,我没法替你判断。
为什么本地好好的,公网就报错

这是这篇文章的重点。
本地 localhost 能跑,不代表换个地址也能跑。把 dev server 暴露到公网后,我遇到的报错大致分三类,对应三个不同的原因。
原因一:WebGPU 需要安全上下文
WebGPU 和很多现代浏览器能力(比如摄像头、部分传感器)一样,要求页面处于安全上下文(secure context) 。安全上下文的判定规则里,localhost 和 127.0.0.1 是被特殊放行的,即使它们是 HTTP。但如果你用 http://192.168.1.x:5173 或者 http://某个公网域名 去访问,就不是安全上下文了,浏览器会直接拒绝暴露 navigator.gpu。
现象通常是这样:页面能加载 HTML 和 JS,但一执行到 navigator.gpu.requestAdapter() 就抛错,或者 navigator.gpu 直接是 undefined。
javascript
// 这段代码在非安全上下文下,navigator.gpu 会是 undefined
if (!navigator.gpu) {
console.error("WebGPU 不可用,可能是非安全上下文或浏览器不支持");
}
【关键结论】想让公网访问也能用 WebGPU,必须走 HTTPS。HTTP + 公网 IP 或域名这条路基本走不通,这不是 Pascal Editor 的问题,是浏览器规范决定的。
原因二:dev server 默认只监听 localhost
很多前端 dev server 默认绑定 localhost,只接受本机连接。你从另一台机器访问,连接根本建立不起来,表现是连接被拒绝或者一直转圈。
要让局域网内其他设备能访问,得让 dev server 监听所有网卡。以 Vite 为例,常见做法是:
bash
bun dev --host
或者在 vite.config.ts 里配置:
typescript
export default defineConfig({
server: {
host: true, // 监听 0.0.0.0
port: 5173,
},
});
具体参数名以你项目实际用的构建工具为准。Pascal Editor 用的构建工具版本不同,配置项可能有出入,这一点我没有逐一验证每个版本,建议以仓库配置文件为准。
原因三:反向代理和 WebSocket 没有正确转发
如果你用 Nginx 之类的反向代理把 dev server 挂到公网域名下,还有一层坑:dev server 的热更新依赖 WebSocket。代理没配好 Upgrade 和 Connection 头,页面能打开但热更新失效,控制台会刷 WebSocket 连接失败的日志。
一个常见的 Nginx 片段大概是这样:
nginx
location / {
proxy_pass http://127.0.0.1:5173;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
但光有这一段还不够,因为上面说的原因一还在------你需要 HTTPS。所以实际部署时,HTTPS 终止通常也放在这一层。
我实际采用的公网访问方案

综合上面三点,我的思路是:本地 dev server 照常跑,外面套一层带 HTTPS 的反向代理。这样 WebGPU 拿到安全上下文,WebSocket 也能转发。
如果你只是想临时给同事演示,不一定非要买域名、配证书。有几个更轻的办法:
- 用内网穿透工具,它通常会自动分配一个 HTTPS 地址,省去自己配证书。具体工具这里不点名推荐,选一个你信得过的即可。
- 自己用
mkcert生成局域网可信证书,配到反向代理上,适合固定内网环境。 - 直接部署到支持 HTTPS 的静态托管或容器平台,但要注意 WebGPU 对跨域资源的要求,模型文件如果从别的域加载,需要对方返回正确的 CORS 头。
第 3 点值得多说一句。WebGPU 本身对跨域纹理、跨域 buffer 有额外限制,如果模型或贴图是从另一个域名拉的,即使主页面是 HTTPS,资源域也得配合返回合适的 CORS 头,否则加载会失败。这个限制比较细,我没有在 Pascal Editor 上逐一验证所有资源类型的表现,但原理上要留意。
方案对比

把几种让公网能访问的做法列一下,方便你按场景挑:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 内网穿透工具 | 配置快,自带 HTTPS | 依赖第三方,地址不固定,可能有带宽限制 | 临时演示、给同事看 |
| 自建 Nginx + mkcert | 完全可控,内网稳定 | 需要自己配证书,只在内网可信 | 固定内网、团队内部 |
| 部署到云平台 | 公网稳定,HTTPS 现成 | 配置复杂,要处理跨域资源 | 长期对外、正式演示 |
| 直接 HTTP 暴露 | 最简单 | WebGPU 直接不可用 | 不推荐,基本跑不起来 |
常见报错和对应排查

把我在过程中见到或合理推断会出现的报错归一下类,方便对照:
navigator.gpu is undefined:先查是不是非安全上下文,再看浏览器 WebGPU 开关。- 页面一直转圈、连不上:dev server 没监听
0.0.0.0,或者防火墙挡了端口。 - 页面能开但热更新失效:反向代理没转发 WebSocket。
- 模型加载失败、控制台报 CORS:资源域没返回正确的跨域头。
requestAdapter()返回null:可能是浏览器/驱动不支持,也可能是安全上下文问题,需要分开排查。
【踩坑提醒】这几个现象有时候会叠在一起。比如你以为是 CORS,其实是安全上下文没满足,navigator.gpu 压根没定义,后面的报错都是连锁反应。排查时从上往下走:先确认安全上下文,再确认 WebGPU 可用,最后才看资源和跨域。
一点个人判断
Pascal Editor 这类把渲染放到浏览器、依赖 WebGPU 的编辑器,本地开发和公网部署的体验差距,比普通 Web 应用要大。普通应用你 --host 一下就能给别人看,它不行,因为 WebGPU 卡了一道安全上下文的门。
所以我的建议是:如果只是自己开发,老老实实 localhost 就行,别折腾公网。如果确实需要远程演示,提前把 HTTPS 这一环准备好,不要等到演示前十分钟才发现 navigator.gpu 是 undefined。
另外,WebGPU 在各浏览器和平台的成熟度还在变化中,今天能跑不代表明天某个版本更新后还一样。如果你在生产环境用,建议锁定浏览器版本范围,并且准备好 WebGL 之类的降级路径------不过 Pascal Editor 是否支持降级,我没有确认,需要你自己看仓库说明。
写到这,本地启动和公网访问这两件事基本讲完了。真正卡人的往往不是代码,而是浏览器那条看不见的安全上下文规则。把它想明白,剩下的就是配代理和证书的体力活了。