文章主要围绕
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,
});
...
}
这就说的通了,代码逻辑判断 非生产环境根本走不到这个逻辑,所以前期发现不了也是正常的。
至此我们得到了哪些关键信息呢?
process.env.PUBLISH_ENV
拿不到导致页面挂了process.env.GM_BUILD_ENV === 'prod'
所以只有生产环境会出问题master
分支部署生产环境没有问题,确实bug是待发布分支引入的哎,一时半会回不了家了,接着分析吧。
跟随上面的结论,直接去看 webpack DefinePlugin
的最终配置(不多废话,自己去看),发现根本就没有 PUBLISH_ENV
这个配置,而且翻遍了 git
记录,至少半年内这个 PUBLISH_ENV
配置就一直不存在。
那就两种可能了
process.env.PUBLISH_ENV
半年内一直都获取不到ok,我们看第一种可能。直接反手切回 master
,接着打印 console.log(process.env.PUBLISH_ENV)
,页面确实没有挂,并且打印了出了一个 undefined
😱,为什么结果不一样,发现了一些端倪,难不成哪个三方包在全局定义了一个 process.env
? 反正业务代码里面没有定义。
在进一步 console.log(process)
,还真是,这是哪位大善人加的 polyfill
啊!
既然能打印出来 process
,那就索性全局搜索一下吧,还真抓住一个可疑分子
process
真的是搜到的这个文件定义的吗?来验证一把,注释 process.env = {}
,然后再重启服务,页面确实如愿的挂了并且得到了一样的报错,那这里先打个问号,究竟是谁帮我打了这个 polyfill
?
经过刚才的验证,实际上第二种可能就不存在了,肯定是新分支在搞事情,看看分支比对吧,究竟是改哪里改到大动脉了!
当我看到
package.json webpack
的版本变更时,我惊呼:woc
tmd我想起来了,我tm踩过一次坑的,没想到有被绊倒了第二次,准确的说不知第几次,总是不能第一时间想起来。
webpack4
升级 webpack5
有 breakchange 啊,webpack@5
不再包含 nodejs polyfills
。
master
是webpack4
会默认兜底 process
,新分支如果没有通过 webpack DefinePlugin
注册那就直接挂呀!!!看了一眼webpack config
,我还特意在项目中针对其他三方包的报错做了恶兼容,只不过漏掉了 process
。
至此探案结束了,当然你也可以通过 node-polyfill-webpack-plugin
这个包去解决,各取所需。
不知道下次还会不会在踩一次,终于可以下班了!