前言
最近手上接到一个任务,webview项目在华为老款手机白屏了,一开始怀疑是js版本不兼容,某些语法没有做pollyfill,于是奔着这个方向,开了dev-server,进行调试,正常的流程不就是这样吗,可是当我在真机上访问开发服务的页面时,vconsole直接报语法错误“# SyntaxError: Use of const in strict mode”,检查获取到的chunk,发现chunk里面仍然会有es6的语法,const这些es6语法在起开发服务的过程中并没有被全部替换,这些es6语法在低版本浏览器肯定无法运行啊,这还怎么调试。 有关devserver产生的chunk为什么会存在es6语法点此查看相关文章,文中提到的解决方案是:
通过降级
webpack-dev-server
到2.7.1
版本使用
babel-loader
时,在非生产环境配置中,额外指定对node_modules/webpack-dev-server/client/index.js
脚本的转换 于是按照上面的教程,试了之后,发现还是不能排除es6语法,看来这个方向不好走啊, 后面我就采取另一个方案,先打生产包,然后借助http-server起一个开发服务,替代webpack的dev-server,尝试后发现不会有es6语法留存,也能正常访问。 此时再打开vconsole,看到的报错就是真实的生产环境遇到的错误了,vconsole中报的错误是 TypeError: Cannot read match of undefined然后是在打包混淆后的chunk文件中的具体的行号,但是并没有标注源码位置,尝试连接edge的inspect,控制台什么都不打印,这样根本不知道错在哪里,无法定位bug, 思考了很久还是觉得应该从source-map入手,于是配置了webapck,在打生产包的时候加上source-map文件,有了source-map文件,还需要手动去关联
在pc端浏览器可以手动关联,但是在移动端似乎不可行,在查阅几篇文章后,我找到了一个利用报错信息和map文件直接显示源码位置的插件,原文地址 插件地址 按照教程,我这边运行指令直接报错,最后把插件的源码打开,改造成js脚本,脚本如下
// Get file content const sourceMap = require('source-map'); const path = require("path") const fs = require("fs") const readFile = function (filePath) { return new Promise(function (resolve, reject) { fs.readFile(filePath, {encoding:'utf-8'}, function(error, data) { if (error) { console.log(error) return reject(error); } resolve(JSON.parse(data)); }); }); }; // Find the source location /** * * @param {String} filePath 打包后的chunk文件对应的map文件的绝对路径 * @param {Number} line 报错的行号 * @param {Number} column 报错的列数 * @returns */ async function searchSource(filePath, line, column) { const rawSourceMap = await readFile(filePath) const consumer = await new sourceMap.SourceMapConsumer(rawSourceMap); const res = consumer.originalPositionFor({ 'line' : line, 'column' : column }); consumer.destroy() console.log(res); return res } searchSource(path.resolve(__dirname,"build/static/js/2.794f4850.chunk.js.map"),2,38516)
在node中执行,果然直接显示出源码的位置信息,最终定位到了bug,顺利解决了bug 上文中提到的那个插件已经不可用,我就想着在此基础上改造出一个新轮子,上传到npm,这也是一个很好的学习机会,嗯,造一些简单实用的轮子,是不是可以更容易进大厂呐。 经过改造的轮子使用方式:
1、全局安装 npm install find-source-location -g
2、 执行命令 fsl -p (map文件路径) -l (报错行号) -c (报错列数)