我的网页游戏在电脑上正常,到了手机却崩了:一次部署故障教会我的事

我把一款网页游戏发布上线了。

自己的电脑能运行。GitHub 里已经是修正后的代码。部署流程也显示成功。

可到了部分手机上,游戏还是会出错。

Analytics 里留下的报错是:

SyntaxError: Unexpected token '<'

我明明写的是 JavaScript,为什么突然冒出来一个“<”?

这是我在制作网页游戏 ORA Quest 时真实遇到的问题。后来我发现,最有价值的并不是某一行“神奇修复代码”,而是弄懂这个报错到底在暗示什么。

真正有问题的,可能根本不是“<”

一开始我以为是 JavaScript 语法写错了。是不是混进了奇怪字符?JSON 坏了?少了一个逗号?

但遇到 Unexpected token '<' 时,很值得先检查一件事:浏览器本来要读取 JavaScript 或 JSON,服务器却是不是返回了 HTML。

比如浏览器请求 game.js,理应拿到 JavaScript。可服务器实际上返回的是一个从 <!DOCTYPE html> 开始的错误页面。

浏览器仍然把它当 JavaScript 解析,于是在第一个 < 就失败了。

也就是说,报错看起来在骂这个符号,真正的问题却可能是:浏览器拿到了不该拿到的文件。

最麻烦的是:它不一定对所有人都坏

这正是这次问题最折磨人的地方。

不是“所有人都进不去”。电脑能跑,某些手机也能跑,但另外一些手机或社交 App 内置浏览器却会失败。

于是很容易陷入这种循环:

改代码 → 部署 → 用自己的电脑打开 → 能运行 → 以为修好了。

我以前也会这样判断。现在不会了。

如果问题和缓存、浏览器、旧资源或特定请求路径有关,那么开发者自己的设备反而可能给出“已经没问题”的假象。

现在再遇到,我会先查这 5 件事

  1. 直接打开出错的 JS 或 JSON URL。
  2. 确认返回内容真的是 JavaScript 或 JSON。
  3. 检查是否返回了 404、登录页、WordPress 页面或其他 HTML。
  4. 确认线上服务器提供的文件,和 GitHub 中预期的文件一致。
  5. 换设备、换浏览器,并尽量排除同一缓存的影响后再测试。

其中第一步尤其重要。

与其看到“JavaScript 报错”就不停改 JavaScript,不如先问一句:

这个 URL 到底返回了什么?

这一个问题,往往能省掉很多无效修改。

GitHub 里正确,不代表用户拿到的就正确

这也是我这次被狠狠教育的一点。

代码仓库里的版本没问题,并不等于用户端收到的一定是那个版本。

中间还可能经过自动部署、服务器、WordPress、缓存、浏览器缓存,以及各种 App 内置浏览器。

只要其中一层还在返回旧文件或意外响应,就会出现“我明明已经修了,为什么用户那里还是坏的”。

所以我现在对“修好了”的定义变了。

不是 commit 正确就算修好,而是生产环境的真实 URL 在接近真实用户的条件下也能正常运行,才算结束。

别只想着消灭报错,还要让下次更容易查

以前一出错,我只想赶快把它弄没。

现在我还会考虑:如果它再出现,我能不能更快知道原因?

是哪个文件失败了?请求的是哪个 URL?用户是什么环境?运行的是哪个 build?

有了这些信息,下次就不再只是“又出现同一个怪错了”,而是可以判断“这和上次是不是同一个原因”。

这种工作不酷,但对一个人维护线上服务来说,可能比多做一个新功能更值钱。

个人开发,很多时候不是“会不会写”,而是“能不能看清到底发生了什么”

开始做网页游戏以前,我以为开发主要是写故事、做角色、写程序。

真正做起来后,大量时间花在了这些问题上:

为什么只有这台设备不行?为什么昨天的 JavaScript 还在?为什么 JSON 地址返回的是 HTML?

每弄明白一个问题,我能做的东西就会多一点。

这次 Unexpected token '<' 给我留下的最大教训是:

“我写下的代码”和“用户实际收到的文件”,并不总是一回事。

如果你现在正被这个错误折磨,先别急着重写代码。直接打开那个出错的 JS 或 JSON URL。要是看到的是 HTML,那已经是非常重要的线索。

我正一边踩这些坑,一边制作网页游戏 ORA Quest。如果你想看看这些排错最后变成了什么,可以免费试玩 ORA Quest。

コメント