如何排查单页面应用的js资源报错问题 (1)
背景:最近项目上有一个使用 h5 页面通过 webview 嵌入 手机的场景,项目是集合很多报告的 h5 页面,因为是最近才建立的,所以技术栈比较新,
第三方库 | 版本 |
---|---|
antd | 5.19.1 |
webpack | 5.99.6 |
react | 18.3.1 |
@ant-design/charts | 2.2.7 |
使用的是单页面应用,通过 webpack 打包成 js 以及 css 资源,然后放到 php 文件中,ios 应用的是这个 php 文件的地址。
问题: 在安卓和最新的 16 版本的 ios 上都正常打开,在 ios 14 版本上打不开,空白页面。
分析: 首先想要知道报错情况。
-
第一步,我在页面中装入 vconsole 插件,引入之后,发现每次打开报错 script error, 于是我打开的亲爱的百度先生,给出的结论是,可能 js 资源语法错误,或者跨域问题。
-
后来通过排查,去除了跨域问题,那么只能语法或者兼容性问题,那么怎么通过script error,去排查哪里的语法或者兼容性问题呢?
-
调试 ios,如果有 mac 的同学,可以使用 ios 在 mac 上调试,首先打开 ios 手机端的 safair 浏览器中的网页检查器,在设置中查找safair 浏览器然后点击进去,选择高级,在里面打开网页检查器,使用 usb 数据线连接手机和 mac, 然后在电脑端 mac 中打开safair 浏览器。打开safair 浏览器的开发这模式,选择菜单中的开发,然后可以看到手机的设备,悬着手机设备中你打开的网页,然后电脑端的 safair 浏览器就自动打开控制台,这时候就可以看到报错信息了,这里的报错信息,显示为SyntaxError: Unexpected private name #initData. Cannot parse class method with private name。通过查询好像是私有类的转化问题,这里就明确知道是低版本的浏览器的兼容问题。
-
但是由于我打包的 js 比较少,只能看到是某个 js 文件报错,也不知道到底是哪里不兼容,我想知道是哪个资源的 js 包报错,我就想起来使用 webpack 打包命名的方式:
output: {
path: path.resolve(__dirname, '../dist'),
filename: `prod.[name].[contenthash].js`,
publicPath: '/kdj-report-pages/',
clean: true,
},
...其他配置
optimization: {
runtimeChunk: 'single', // 将运行时代码合并到单独文件
splitChunks: {
// chunks: 'all',
// minSize: 1000000, // 500KB 以下不拆包
// maxSize: 3000000,
// minChunks: 1,
// maxAsyncRequests: 6,
// maxInitialRequests: 4,
// automaticNameDelimiter: '~',
cacheGroups: {
reactVendor: {
test: /[\\/]node_modules[\\/](react|react-dom|react-router|react-router-dom|react-redux|redux-logger|react-draggable|@reduxjs\/toolkit)[\\/]/,
// name: 'vendors-react',
filename: 'prod.vendors-react.js',
priority: 20,
chunks: 'all',
reuseExistingChunk: true
},
antdVendor: {
test: /[\\/]node_modules[\\/]antd|@ant-design\/charts[\\/]/,
// name: 'vendors-antd',
filename: 'prod.vendors-antd.js',
priority: 15,
chunks: 'all'
},
utilityVendor: {
test: /[\\/]node_modules[\\/](lodash|moment|axios|decimal.js|clipboard|viewerjs)[\\/]/,
name: 'vendors-utils',
// filename: 'beta.vendors-utils.js',
priority: 10,
chunks: 'all'
},
defaultVendors: {
test: /[\\/]node_modules[\\/]/,
name: 'vendors-common',
// filename: 'vendors-common.js',
priority: 5,
chunks: 'all',
reuseExistingChunk: true
}
}
}
},
通过splitChunks,将包分类,然后使用 filename: prod.[name].[contenthash].js
,进行命名,打出的包之后,在 safair 浏览器中看到了报错,是node_modules 里面的 js 报错。
- 这时候我使用了 ai ,将报错的代码给他分析,定位出具体的代码是哪个 js 包,最后分析出是 @ant-design/charts 的某个饼状图不兼容
- 这时候你可以使用更换的办法解决,因为项目中排查,只有一个地方造成了不兼容,我进行了更换处理,解决了问题,看到 ai 的回答还可以通过一下 babel 插件 + 搭配@babel/preset-env + core.js 解决