如何快速定位SSR项目中只在线上环境出现的报错

背景

在做SSR项目开发的时候,碰到过几次报错:本地调试是正常的,只在线上环境会报错

  • 有些报错影响也很大:导致js加载错误,js功能全部无效
  • 因为只在线上会报错,导致调试起来很麻烦

解决办法

目前有2个办法

  1. 模拟线上环境去调试
  2. 使用框架的线上版本

方法1. 模拟线上环境去调试

原理:

  • 本地模拟线上环境。包括线上版本的包,起服务,开代理等

步骤可以分为:

  1. npm run build 先打一个线上版本的包
  2. 本地起node服务,来启动这个包
  3. 可选:配whistle代理,可以调试线上接口

步骤是比较简单,但里面会有些细节

  1. 比如run build时,要注意资源的打包的output路径(正常情况下,基本上SSR的静态资源都是要打包到CDN上去的。此处我们要打到本地,所以output的路径要注意修改)
  2. 视情况而定,打包时可以去掉丑化压缩,增加source map等,方便调试
  3. 起本地服务时,可以用框架提供的,比如nuxt框架,可以用nuxt start起服务

这个方案的好处:

  1. 如果SSR有内存泄漏问题,可以用此方案排查(打包时去掉丑化压缩等,方便调试)
  2. 可以得到SSR服务的处理能力。比如QPS等
  3. 排查只出现在线上环境的报错

方法2. 使用框架的线上版本

如果使用了框架(vue/react等)的话,那么大概率在dev环境下,把框架换成线上版本,就能在本地复现了

  • 可以直接run dev调试了。比run build + 改配置要简单很多
  • 框架在dev环境,默认会用dev的版本包

配置示例,比如:

// 改webpack配置的alias
config.resolve.alias = {
    ...
    vue$: path.resolve(
      './node_modules/vue/dist/vue.runtime.min.js'
    ),
}

这个方案的好处:

  1. 调试bug方面,比方案一要简单,还有热更新的功能。方案一没有热更新,要重新打包,重启服务才行

另外举例:一个SSR服务常见,但很棘手的报错

棘手的原因是:只有线上环境会报错,并js全部失效。去掉丑化压缩和打开sourcemap,都一样报这个错(没有额外信息)

如何快速定位SSR项目中只在线上环境出现的报错

一行一行代码注释调试后… 注释到 组件库代码时,解决了…

  1. 报错倒是很简单看,我们是SSR服务。报错是说没拿到dom。但没想到是组件库内的…
  2. 错误原因:无外乎就是组件库在created 或 beforeCreate 执行了dom操作

最终解决:

  • 为问题组件 套一层 <client-only>...</client-only> (nuxt项目)

总结:

  1. 报错既然在 去掉丑化压缩和打开sourcemap,都一样的,并且是webpack-internal,则说明大概率是 三方依赖导致的

  2. 会操作dom的三方依赖,大概率是组件库


码字不易,点赞鼓励!!