cover_image

一行代码,一次故障,一段邂逅

张匀重 Goodme前端团队
2025年01月13日 00:30

温馨提示

文章主要围绕 webpack 升级到 5.x 之后不再包含 nodejs polyfills 这个breakchange去讲述的。如已知此变更,大可不必浪费时间阅读,除非你想划水!!

相识

那是一个普通的周四晚上,刚准备收拾包准备溜;

突然同事跑过来找我说:出事啦,线上白屏啦!

啊,我心想:怎么会!这次taro@3.6的升级应该是十拿九稳的,前面十几个应用都顺利上线了,咋到这白屏了?

赶紧打开应用验证,直接访问链接就白屏了,devtool中抓到了错误Uncaught ReferenceError: process is not defined,看到报错第一反应就是环境变量没注入?转念一想,不对啊,之前不都好好的吗?本地开发没问题?测试阶段怎么过的?这不是必现的问题吗? 满脑子的问号???

发现异样

先第一时间回滚吧,边回滚同事边和我说:测试环境和预发环境我们都回归通过了才的发布的正式环境,没想到发布完一打开就白屏了。

带着一脸疑问开始分析代码,又去生产环境抓了下这条错误的堆栈,初步定位问题出现在下面这一段代码。

// 应用入口页面
XXX.init({
  ...
  environment: process.env.PUBLISH_ENV,
});

很熟悉对吧,难道就因为 process.env.PUBLISH_ENV 这个环境变量没注入这么easy?前端高手已经遇见过无数次这种报错了对吧,但我感觉事情并没那么简单。

先复现试试,切换到待发布分支,启动后一切正常,确实没有报错;可以,小伙子没有骗我。

直接打印下 console.log(process.env.PUBLISH_ENV),页面直接挂了,报错和线上一致,可以直接锁定就是这一行代码导致页面白屏了!

但为啥发布正式环境就挂了?没其他头绪了接着看代码吧,发现这段代码外面还套了一层判断。

if (process.env.GM_BUILD_ENV === 'prod') {
  ...
  XXX.init({
    ...
    environment: process.env.PUBLISH_ENV,
  });
  ...
}

这就说的通了,代码逻辑判断 非生产环境根本走不到这个逻辑,所以前期发现不了也是正常的。

至此我们得到了哪些关键信息呢?

  1. process.env.PUBLISH_ENV 拿不到导致页面挂了
  2. 因为有 process.env.GM_BUILD_ENV === 'prod' 所以只有生产环境会出问题
  3. 回滚后一切正常,说明master分支部署生产环境没有问题,确实bug是待发布分支引入的

接近真相

哎,一时半会回不了家了,接着分析吧。

跟随上面的结论,直接去看 webpack DefinePlugin 的最终配置(不多废话,自己去看),发现根本就没有 PUBLISH_ENV 这个配置,而且翻遍了 git 记录,至少半年内这个 PUBLISH_ENV 配置就一直不存在。

那就两种可能了

  1. 要么 process.env.PUBLISH_ENV 半年内一直都获取不到
  2. 要么被我们这次升级碰巧改没了,哪里改的还未知

ok,我们看第一种可能。直接反手切回 master,接着打印 console.log(process.env.PUBLISH_ENV),页面确实没有挂,并且打印了出了一个 undefined 😱,为什么结果不一样,发现了一些端倪,难不成哪个三方包在全局定义了一个 process.env ? 反正业务代码里面没有定义。

在进一步 console.log(process),还真是,这是哪位大善人加的 polyfill 啊!

图片
image.png

既然能打印出来 process,那就索性全局搜索一下吧,还真抓住一个可疑分子

图片
image.png

process 真的是搜到的这个文件定义的吗?来验证一把,注释 process.env = {},然后再重启服务,页面确实如愿的挂了并且得到了一样的报错,那这里先打个问号,究竟是谁帮我打了这个 polyfill?

图片
image.png

再次邂逅

经过刚才的验证,实际上第二种可能就不存在了,肯定是新分支在搞事情,看看分支比对吧,究竟是改哪里改到大动脉了!

图片当我看到 package.json webpack 的版本变更时,我惊呼:woc

tmd我想起来了,我tm踩过一次坑的,没想到有被绊倒了第二次,准确的说不知第几次,总是不能第一时间想起来。

webpack4 升级 webpack5 有 breakchange 啊,webpack@5 不再包含 nodejs polyfills

图片
image.png

master 是webpack4 会默认兜底 process,新分支如果没有通过 webpack DefinePlugin 注册那就直接挂呀!!!看了一眼webpack config,我还特意在项目中针对其他三方包的报错做了恶兼容,只不过漏掉了 process

图片
image.png

至此探案结束了,当然你也可以通过 node-polyfill-webpack-plugin 这个包去解决,各取所需。

不知道下次还会不会在踩一次,终于可以下班了!


个人观点,仅供参考
继续滑动看下一个
Goodme前端团队
向上滑动看下一个