无题
中后台系统表单比较多,每次调试都要填一堆东西,而且项目需要登录,经常需要来一遍登录流程,再填写表单来调试。这个流程还是比较繁琐的。
于是我在想,自动化测试工具 puppeteer 是可以通过脚本来自动执行浏览器操作的,能不能调试的时候让 puppeteer 帮我自动做了页面操作的一些流程呢?
我试了一下还真可以,用 puppeteer 来自动执行脚本,并且过程中还可以打断点调试,调试体验简直不要太爽。
这节就来分享下。
首先,react 项目是通过 vscode debugger 来调试的:
在 .vscode > launch.json 的调试配置文件里新增一个 chrome 类型的调试配置,输入调试的 url。
然后点击 debug 启动:
执行到代码中的断点就会在 vscode 里断住:
这样就可以在 vscode 里断点调试 react 项目了。
但登录还是比较麻烦的,用户名密码我经常忘,而且登录之后还要填一些表单,也很麻烦。
这时候我想到了 puppeteer。
它是可以自动执行脚本的。
比如这样一段脚本:
1234567891011121314151617181 ...
无题
前端的命令行工具太多了,比如 webpack、vite、babel、tsc、eslint 等等,每天我们都会用各种命令行工具。
这些命令行工具都提供了两种入口:命令行和 api。
平时用我们会通过命令行的方式,比如 eslint xxx –fix,但是别的工具集成这些工具的时候就会使用 api 了,它更灵活。
所以,调试这些工具的时候也就有两种方式,通过命令行调试和通过 api 调试。
这节我们以 eslint 为例子来试下两种调试方式,大家可以跟着调试一下。
命令行的方式调试 ESLint 源码我们创建一个 index.js 文件
配置下 .eslintrc
123module.exports = { extends: 'standard'}
安装 eslint,然后执行 npx eslint ./index.js 会看到这样的报错:
后面三个错误都是格式错误,eslint 可以修复。
执行 npx eslint ./index.js –fix 就会自动修复错误。
我们想探究下 fix 的原理,就要调试下源码了。
用 ...
无题
有时候我们需要修改 node_modules 下的一些代码,但是 node_modules 不会提交到 git 仓库,改动保存不下来,怎么办呢?
这时候可以用 patch-package 这个工具。
比如我对 node_modules 下的 acorn 代码做了一些修改:
加了一个 a.js 的文件:
在项目目录下执行 npx patch-package acorn 之后,就会生成这样一个目录:
在 patches 目录下的 xx.patch 文件里记录着对这个包的改动。
这个 patches 目录是可以提交到 git 仓库的,然后再次把项目拉下来的时候,执行下 npx patch-package 就会应用这次改动。
可以把它配到 postintsll 里,每次安装完依赖自动跑。
这样能保证每次拉取下来的代码都包含了对 node_modules 的改动。
如何使用我们学会了,那它是怎么实现的呢?
这节我们就来调试下 patch-package 的源码。
调试 patch-package 源码首先把代码下载下来:
1git clone git@github.com:ds300/ ...
无题
Babel 是一个 JS 的编译器,用于把高版本语法的代码转成低版本的,并且添加 polyfill。
它有很多插件,插件还进一步封装成了预设(preset),开箱即用。
此外,我们还可以写 Babel 插件来完成一些特定的代码转换。
Babel 是前端领域高频用到的工具,自然有必要去深入它的原理。所以这节我们就来调试下 Babel 的源码。
Babel 也是个命令行工具,也是有命令行和 api 两种形式的入口。今天我们通过 api 的方式来调试它。
它的编译流程分为三个阶段:
parse:把源码转成 AST
traverse:对 AST 做遍历,遍历过程中做增删改
generate:生成目标代码和 sourcemap
这三个阶段分别对应 @babel/parser、@babel/traverse、@babel/generator 三个包。
它的 API 是这样用的:
123456789101112131415161718192021222324const parser = require('@babel/parser');cons ...
无题
Vite 这两年比较火,大家应该都接触过它,但很少有人调试过它的源码。而想要深入理解它的原理,调试源码是必不可少的一步。
这节我们就一起来调试下 Vite 的源码。
首先,用 create-vue 创建一个 vite + vue3 的项目:
执行 npm init vue@3,然后进入项目目录,安装依赖。
之后 npm run dev 把 vite 的开发服务跑起来:
那么问题来了,vite 跑 dev server 的过程都执行了什么逻辑?
这就要调试源码来找答案了。
创建 .vscode/launch.json 的配置文件,添加一个 npm 类型的调试配置:
指定用调试的方式跑 npm run dev:
其他的都是默认配置,但要指定下 console 为 integratedTerminal,这样会把日志打在我们平时用的那个集成终端里。不然默认是打在这里的:
可以在 vite.config.js 这里打个断点:
因为这个 defineConfig 肯定是被 vite 调用的,我们可以看下 vite 处理配置的代码。
调试的方式跑,代码会在这里断住:
往下执行一 ...
无题
不知道大家对 ts 是否熟悉,你觉得下面这段 ts 代码,res 类型是什么?
123type Test<T> = T extends number ? 1 : 2;type res = Test<any>;
结果是 1 | 2 的联合类型:
很多同学会感到迷惑,为什么是这样呢?
这就要从源码找答案了,今天我们就来调试下 ts 源码来探究上面这个类型的求值过程。
首先,我们要把 ts 源码下载下来(加个 depth=1 可以下载单 commit,速度比较快),这里我下载的是 4.6.0 版本的源码
1git clone --depth=1 git@github.com:microsoft/TypeScript.git
然后可以看到 lib 目录下有 tsc.js 和 typescript.js,这两个分别是 ts 的命令行和 api 的入口。
但是,这些是编译以后的 js 代码,源码在 src 下,是用 ts 写的。
怎么把编译后的 js 代码和 ts 源码关联起来呢? sourcemap!
编译源码:
12yarn yarn run build ...
无题
我们学习了如何调试网页和 Node.js 的代码,可以在代码某一行打个断点,代码执行到这里的时候就会断住,可以看它的作用域、调用栈等。
但有的时候,我们并不知道应该在哪里打断点:
比如代码抛了异常,你想打个断点看看异常出现的原因,但你并不知道异常在哪里发生的。
比如 dom 被某个地方修改了,你想打个断点看看怎么修改的,但你并不知道是哪段代码修改了它。
比如有的断点你想只在满足某个条件的时候断住,不满足条件就不需要断住。
类似的情况有很多,需要断住,但是普通的断点又不大合适,这时候就需要其他的断点类型了。
我们分别来看一下:
异常断点代码抛了异常,你想知道在哪抛的,这时候就可以用异常断点。
比如这样一段代码:
123456function add(a, b) { throw Error('add'); return a + b; }console.log(add(1, 2));
add 函数里抛了个异常,你想在异常处断住,这时候就可以加个异常断点:
用 node 的调试来跑:
勾选 Uncaught Excepti ...
无题
写 react 项目的小伙伴应该都用过 antd 组件库,但绝大多数同学并没有看过它的源码。
而想深入掌握 antd 组件库,只熟悉参数是不行的,必须要深入到源码层面。
所以今天就来分享下如何调试 antd 的源码。
而且我敢说这种调试源码的方式 90% 的前端都不会。
为什么呢?看到后面你就知道了。
首先,我们用 create-react-app 创建一个 react 项目:
1yarn create react-app antd-react-test
创建成功后,进入到项目里,把 dev server 跑起来。
浏览器访问可以看到渲染出的页面:
然后我们安装 antd,在入口组件里引入样式和 Button 组件:
页面会显示这个 Button:
那怎么调试这个 Button 组件的源码呢?
可以这样:
首先,创建一个 VSCode 调试配置:
指定调试的 URL,然后启动调试。
在组件里打个断点,代码会在这里断住:
可以看到调用栈中上一帧是 renderWithHooks,这就是 react 源码里调用函数组件的地方。
点击那个调用栈,你就会看到:
它调用了 App ...
无题
上节写了怎么调试 antd 的源码,但很多小伙伴是写 Vue 的,可能平时用的是 Element UI 的组件库,所以这节就来讲下怎么调试 Element UI 的源码。
首先,我们用 Vue CLI(用 vue cli5) 创建一个 vue2 的项目:
123yarn global add @vue/clivue create element-vue-test
创建成功后,进入到项目目录
安装 element ui 的库,并在入口引入:
然后在 App.vue 里用一下 button 组件
之后 yarn run serve 把开发服务跑起来,就可以看到这样的页面:
Element UI 的组件正确的显示了。
接下来调试 button 组件的源码,那问题来了,我怎么知道在哪里打断点呢?
我们可以知道的是,这个 button 会处理点击事件,但是却不知道事件处理函数的代码在什么地方。
这种情况可以加一个事件断点:
在 sources 面板的 Event Listener Breakponts 里勾选 Mouse 的 click 事件,也就是在所有 click 事件的处理函数 ...
无题
网页加载后,浏览器会解析 html、执行 js、渲染 css,这些工作都是在 Event Loop 里完成的,理解了 Event Loop 就能理解网页的运行流程。
但很多人对 Event Loop 的理解只是停留在概念层面,并没看过真实的 Event Loop 是怎样的。
其实在 Performance 工具里就可以看到,今天我们一起来看一下:
首先我们需要一个网页,我这里用的是 react 测试 fiber 用的网页:
https://claudiopro.github.io/react-fiber-vs-stack-demo/fiber.html
点击 Performance 面板的 reload,录制 3 s 的数据:
其中 Main 这部分就是网页的主线程,也就是执行 Event Loop 的部分:
这块区域包含了所有 task 执行的流程,每个 task 的调用栈,因为像燃烧的火焰,所以也叫做火焰图。
鼠标划到想看的部分,向下拖动,就可以放大那个区域:
左右上下拖动可以调整看的位置:
展示的信息中很多种颜色,这些颜色代表着不同的含义:
灰色就代表宏任务 task: ...
