vue-devtools使用方法与源码分析

572 阅读4分钟

前言 在实际的开发中,经常会用到vue-devtools插件去快速的的打开组件的源码,但是对它的实现逻辑不是很清楚。官网给出的定义是:Vue Devtools 是 Vue 官方发布的调试浏览器插件,可以安装在 Chrome 和 Firefox 等浏览器上,直接内嵌在开发者工具中,使用体验流畅。 目前该插件有两个版本,支持Vue3的Beta版本,和支持Vue2的版本。

学习目标: 1 如何调试源码; 2 了解vue-devtools插件是如何在浏览器中直接通过编辑器打开组件; 3 vue-devtools的底层原理; 4 通过对源码的阅读,扩展对源码中优秀代码的认知;

1 如何调试代码(Vscode)

​打开项目下的package.json页面,点击调试,并在下拉框中选择serve,然后系统会默认打开终端执行npm run serve脚本命令启动调试项目。 ​​https://img-blog.csdnimg.cn/direct/4acb173454ba494290fcac79476f792e.png 在这里插入图片描述

2 准备工作

vue-devtools是vue框架自带的一个插件,当我们用vue-cli创建Vue项目时,该插件会包含在node_modules中。这里创建一个新的项目

vue create demo-project
npm install

3 源码分析

3.1 vue-devtools是如何打开源码的

打开组件源码的方式 在这里插入图片描述 当我们点击打开App.vue组件时,可以在network中看到,会执行http://localhost:8080/__open-in-editor?file=src/App.vue请求。我们将http://localhost:8080/__open-in-editor?file=src/App.vue地址放到浏览器地址栏直接访问,可以直接打开对应的源码 在这里插入图片描述

以下源码解析都以打开http://localhost:8080/__open-in-editor?file=src/App.vue为例

3.2 入口文件

有了打开地址,我们就可以根据这个地址去查找入口文件 我们去源码中看第一个识别__open-in-editor是serve.js文件 在这里插入图片描述

3.3 launch-editor-middleware中间件

在==launch-editor-middleware==中间件中,接收传过来的参数,并最终调用==launch-editor==中间件 接收传过来的参数specifiedEditor, srcRoot, onErrorCallback

onErrorCallback = 当specifiedEditor或srcRoot为函数时赋值 srcRoot是传递过来的参数,或者当前node进程的目录

在这里插入图片描述 这里其实用了参数切换,我们可以看到launchEditorMiddleware函数接受了三个虚参,但实际用户调用可能就想传一个参数,而且是传给第二个虚参的,这个时候就可以根据第一个参数的参数类型做判断,来确认用户传的这个参数其实是给指定的虚参的。 比如这里如果第一个参数specifiedEditor如果是函数,则表示用户其实想赋值给onErrorCallback的,则切换参数。

3.4 launch-editor中间件

launchEditor函数接收三个参数,第一个参数为当前目标文件的绝对路径,第二个是编辑器,第三个错误处理函数。 我们打断点看一下函数内部。 在这里插入图片描述

3.4.1 parseFile

parseFile函数就是解析并提取文件路径、行号、列号的

// 对file文件路径处理:
const parsed = parseFile(file)
let { fileName } = parsed
const { lineNumber, columnNumber } = parsed

const positionRE = /:(\d+)(:(\d+))?$/
function parseFile (file) {
  const fileName = file.replace(positionRE, '')
  const match = file.match(positionRE)
  const lineNumber = match && match[1]
  const columnNumber = match && match[3]
  return {
    fileName,
    lineNumber,
    columnNumber
  }
}

3.4.2 wrapErrorCallback

在onErrorCallback错误函数的基础上,再打印更多的错误日志

function wrapErrorCallback (cb) {
  return (fileName, errorMessage) => {
    console.log()
    console.log(
      colors.red('Could not open ' + path.basename(fileName) + ' in the editor.')
    )
    if (errorMessage) {
      if (errorMessage[errorMessage.length - 1] !== '.') {
        errorMessage += '.'
      }
      console.log(
        colors.red('The editor process exited with an error: ' + errorMessage)
      )
    }
    console.log()
    if (cb) cb(fileName, errorMessage)
  }
}

在这里插入图片描述

3.4.3 guessEditor

guessEditor的内部执行逻辑: 1、specifiedEditor是否指定编辑器,指定直接返回 2、specifiedEditor未指定

  • 根据系统来创建不同子进程的sell命令
  • 获取当前所有的进程
  • 遍历进程信息的数组,获取到的进程最后的文件名和该系统预写的编辑器匹配,匹配上就返回 在这里插入图片描述 在这里插入图片描述

3.4.4 子进程child_process

child_process是node中用于创建子进程的内置模块,因为我们要打开指定文件,就需要新增一个子进程去执行。 在这里插入图片描述

4 总结

这是我第二次尝试进行源码阅读,总体来说比较吃力,阅读很慢,断点也不太会用,源码阅读能级亟待提高。就是现在感觉对这部分的源码还是没有完全的吃透,希望等以后源码能力上来了,再来重新的巩固一下,相信会有不一样的收获 参考网站 解锁vue-devtools的"隐藏"技能 vue-devtools 还能直接打开对应组件文件 vue-devtools 打开组件分析