前端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库
这篇文章来分享下如何调试线上的代码
什么时候需要调试线上的代码呢,当线上代码出现 bug 的时候,需要定位问题,就需要一步一步调试代码来确认问题,但是线上代码都是构建之后的代码,很难看懂,有什么好的解决办法么?
实际例子
在本地创建一个 demo 项目
mkdir debugger-demo cd debugger-demo npm init -y npm i webpack webpack-cli
这个项目用 webpack 构建打包
这是 webpack 配置文件 webpack.config.js :
const path = require("path"); /**@type {import('webpack').Configuration} */ module.exports = { mode: "production", entry: "./src/index.js", output: { filename: "index.js", path: path.resolve(__dirname, "dist"), } };
tips:在编写js配置文件的时候,如果没有好的编译器提示,可以借用 JsDoc
入口文件时"./src/index.js"
,输出文件是"./dist/index.js"
。很简单的配置文件
下面准备入口文件 index.js:
const data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; const _generate = (data, index) => { if (!data[index]) return null; const root = { value: data[index], left: null, right: null }; root.left = _generate(data, index * 2); root.right = _generate(data, index * 2 + 1); return root; }; // 构建二叉树 const generate = (data) => { return _generate(data, 1); }; const tree = generate(data); // 二叉树前序遍历,非递归 const printInOrder = (tree) => { const stack = []; let node = tree; while (node || stack.length !== 0) { while (node) { stack.push(node); node = node.left; } const popNode = stack.pop(); console.log(popNode.value); node = popNode.right; } }; printInOrder(tree);
这是一段二叉树生成,以及遍历的代码,代码稍稍有些复杂,为了调试做点铺垫
执行npx webapck
,将代码打包
打包完成后,在 dist 文件夹下面生成了 index.js:
下面手动创建一个 index.html, 然后将 index.js 文件引入进去:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <script src="./index.js"></script> </body> </html>
在浏览器中打开:
代码正确执行
现在往代码里添加一个 throw
,让其报错:
// 二叉树前序遍历,非递归 const printInOrder = (tree) => { const stack = []; let node = tree; while (node || stack.length !== 0) { while (node) { stack.push(node); node = node.left; } const popNode = stack.pop(); console.log(popNode.value); node = popNode.right; throw ""; // 抛出错误 } };
然后在浏览器中勾选这一项,浏览器就会自动停在报错的地方了:
刷新浏览器:
发现代码确实停在了报错的地方,但是代码经过构建,变量名都变了。要是代码再复杂一点,就更不忍直视了。
我们在调试线上代码的时候估计也是这个样子。这个时候,就可以请出我们的法宝:sourcemap
使用 sourcemap
soucemap 是一个描述文件,调试工具可以通过这个文件,将构建代码映射成构建之前的文件。
修改 webpack 配置文件:
const path = require("path"); /**@type {import('webpack').Configuration} */ module.exports = { mode: "production", entry: "./src/index.js", output: { filename: "index.js", path: path.resolve(__dirname, "dist"), }, devtool: "source-map", };
添加生成 source-map 的配置,就会生成 sourcemap 了:
并且构建后的文件末尾就会出现:
浏览器会通过 souceMappingURL 获取 sourcemap,获取完成之后就会自动完成映射。
完成映射就会自动地显示构建之前的代码
但这是生产环境,是不可以让其他人看见源码的。那该怎么办呢?
可以换个 devtool 配置:
const path = require("path"); /**@type {import('webpack').Configuration} */ module.exports = { mode: "production", entry: "./src/index.js", output: { filename: "index.js", path: path.resolve(__dirname, "dist"), }, devtool: "hidden-source-map", };
hidden-source-map
的意思是生成 sourcemap,但是不会关联 sourcemap,也就是不会自动地在构建之后的文件末尾添加 sourceMappingRUL,这样浏览器就看到不到。
虽然浏览器看不见了,但开发人员不也看不见了?不用担心,开发人员可以手动添加 sourcemap
在浏览器中打开构建之后代码文件,然后右键,就可以看到 add sourcemap
的选项
然后填上 soucemap 的路径就可以了。soucemap 的路径和 index.html 相同
点击 Add 后,就可以看见源代码了:
总结:
这篇文章分享了如何调试线上代码,主要的点是 webpack 的配置和 浏览器自动添加 add sourcemap 的功能,当然,这两点都归结于 sourcemap 的映射能力。
前端面试题库 (面试必备) 推荐:★★★★★
地址:前端面试题库