项目背景
Electron 项目里打开的 web 页面,技术栈是 React
项目的监控报错机制使用 sentry,但只有错误却拿不到源码中的报错堆栈其实意义不大,所以需要上传 sourcemap
然后,坑来了
先列一下我在项目中使用的 sentry 相关依赖及其版本
"@sentry/browser": "^6.7.1",
"@sentry/tracing": "^6.7.2",
"@sentry/webpack-plugin": "^1.16.0",
安装依赖过程中遇到的问题
@sentry/webpack-plugin
会连带下载 sentry/cli,后者是配合 webpack 插件自动上传 sourcemap 的工具,但是一直下载不下来,最后使用集团的 npm 源解决,package.json 里这样配置 直接使用淘宝的镜像源就行了,这里也有坑,之前淘宝的镜像源是 cdn.npm.taobao.org/dist/sentry… 但现在应该是已经废弃了,使用 npm.taobao.org/mirrors/sen… 即可
// package.json
{
... other config
"publishConfig": {
"registry": "https://npm.mycompany.com/"
},
}
上传 sourcemap 过程中遇到的问题
配置 sentry 收集错误很简单,照着文档来就好了,很容易就能在 sentry 后台抓到报错;但在上传 sourcemap 的时候,怎么都实现不了错误和源码的对应,具体报错如下:
最开始看到文件太大无法缓存,就去做针对性的解决,重新配置 webpack 分包策略,可是把包拆小以后,就又出来了第二个 source code not found 的报错,绕了一大圈,感觉没什么用,还是得从 web 项目本身的配置着手,于是仔细对照文档,找到了问题所在,首先是 webpack 的 devtool 的配置,必须是 sentry 文档中的 source-map 或者 hidden-source-map,其次就是 sentrycli
里的 urlPrefix 配置这个也很重要,假如 js 资源加载的地址是:
https://wwww.mycompany.com/assets/js/vendor.js
,那 urlPrefix 就需要配置成这个样子:urlPrefix: '~/assets/js',
,其中 ~
代表网站根目录
说的再直白点,wwww.mycompany.com
是网站域名,域名后面的拼到 urlPrefix 里
这里不要跟下面配置中的 include
混淆,include 是设置 sentry 该去哪个目录下找打包完成的 js 和 map 文件去上传,与实际静态资源的加载地址没有直接关系
网上的文章对于生成 authToken 需要勾选哪些权限说法不一,当时开发的时候报错一直解决不掉,所以我在生成 authToken 的时候索性全部勾上了,排除它的干扰
最后说一下 release,如果在 sentrycli
里配置了release,那么在业务代码中 Sentry.init() 的时候也要传入,且必须保持一致,比如可以使用 package.json 里的 version
也可以不配置,这样每次构建上传 sourcemap,会自动生成一个随机字符串作为此次的 "release",sourcemap 也是可以正常生效的
总之一句话,要配就两个地方都配,要么就不管 release 这个字段,都是可以的
release: '',
url: 'https://sentry.mycompany.com/',
authToken: '',
org: '',
project: '',
include: path.resolve(__dirname, './dist/static/'),
ignore: ['node_modules', 'webpack.common.js', 'webpack.dev.js', 'webpack.prod.js'],
urlPrefix: '~/path/path',
sentry 中拿到的错误状态
- 最开始上传 sourcemap 后抓到错误的展示情况
这个时候 sourcemap 虽然上传成功了,但是 sentry 自身就有报错,所以完全没有效果,如下图,可以看到只能够展示错误是在构建产物比如 vendor.js 里的,具体哪行什么地方不知道,对于调试意义不是很大
- prefixURl 错误的效果
经过修改,上传了正确格式的 sourcemap。如下图右下方红框圈起来的地方,可以看到出错的 JS 文件可以展开收起展示报错的相关代码了,但还是无法和 sourcemap 正确映射匹配
- 完成的效果
可以直接拿到错误在源码中的位置。如下图右侧两个红框圈起来的地方,出现了
原始的/最小化
的切换按钮。到这一步,就完成了。