还在找源文件?从 vue 前端页面一键打开源码所在文件

10,833 阅读2分钟

背景

开发中遇到的痛点

在开发前端应用的过程中,修改页面内容的途径就是找到对应的源文件,并修改对应的代码。如果同时在调试多个页面功能,或者项目架构命名混乱,则将会有大量时间浪费在找文件上。真的是开发 5 分钟,查找 2 小时。。。

所以如果有一种方式可以直接通过页面打开源文件,那么开发效率则会有明显提升!

现存的解决方案

我接触的 vue 项目居多,所以就说说 vue 里面现有的解决方案

vue-devtools

vue-devtools 有打开 editor 的功能,但是需要频繁打开控制台、选择组件、点击按钮进行操作,个人觉得还是不够简便。

目标

最终想达到点击元素直接通过编辑器打开源代码的对应位置,就像使用 ctrl + c/v 一样流畅!

1 定位到页面级别

在实现最终目标之前,我们先从最简单的开始做起,能否先通过元素打开当前所在页面呢?

找到页面文件的路径

想要打开文件,必须先知道文件的绝对路径,幸运的是 vue-router 将页面的路径信息就储存在$route里面。

可以这样拿到文件路径:

this.$route.matched[0].components.default.__file

打开编辑器

如果你使用的是 vscode,则可以通过终端使用 code命令在编辑器内打开文件。这就为我们使用命令打开编辑器称为可能。

code a.js

实现打开动作

接下的要做的是前端将文件路径传递给一个后端服务,让后端服务通过nodejs执行code命令

前端

    // 前端页面
	const filePath = this.$route.matched[0].components.default.__file
    const devServerPort = 8700;
    axios.get(`http://localhost:${devServerPort}/code`, {
      params: {
        filePath: `-g ${filePath}`
      }
    });

后端

  // webpack devServer 配置
  devServer: {
    port: 8700,
    before: function (app) {
      const child_process = require("child_process");
  
      app.get("/code", function (req, res) {
        child_process.exec(`code ${req.query.filePath}`);
        res.send("文件打开成功!");
      });
    }
  },

webpack 的 devServer 本身就是一个服务,所以我们可以通过对其进行配置来添加我们自己的逻辑

2 定位到组件级别

通过上面的操作可以跳转到页面的源码,但是如果能直接跳转到组件则更实用

找到组件的路径

在使用 vue-loader 解析 vue 文件时,通过配置 exposeFilename 属性可以将组件的路径放到组件实例中

vue-loader 文档

  // vue.config.js
  chainWebpack: config => {
    // ...
    config.module
      .rule('vue')
      .use('vue-loader')
      .loader('vue-loader')
      .tap(options => {
        options.exposeFilename = true
        return options
      })
  },

并可以通过这样获取到组件文件路径:

this.$options.__file

组合键点击组件触发操作

获取到组件路径了,下一步可以给组件注册点击事件,就可以完成点击组件跳转到源码。

这里将注册点击事件的逻辑写在一个 vue 插件里,插件内部用 mixin 在每个组件挂载的时候都给每个组件都注册一个事件。

同时这里采用了 alt + 左键 组合点击的方式,为了避免和普通的业务操作相互混淆

// client.js
import axios from "axios";
import Vue from 'vue'

function launchEditor(filePath) {
  if (!filePath) return
  const devServerPort = 8700

  axios
    .get(`http://localhost:${devServerPort}/code`, {
      params: {
        filePath: `-g ${filePath}`
      }
    })
}
const openComponentPlugin = {
  install(Vue) {
    Vue.mixin({
      mounted() {
        this.__injectedFn = (e) => {
          if (e.altKey) {
            e.preventDefault()
            let filePath = this.$options.__file

            if (filePath) {
              e.stopPropagation()
              launchEditor(filePath)
            }
          }
        }
        this.$el.addEventListener('click', this.__injectedFn)
      },


      destroyed() { 
        this.$el.removeEventListener('click', this.__injectedFn)
      }
    });
  }
};
Vue.use(openComponentPlugin);


// main.js
import  "./client";

效果

这样点击跳转的体验是不是比手动找文件好很多!!

后续

目前实现了点击组件进入源代码了,不过当组件过大时,还是需要二次查找代码的具体位置。下篇将讲述:如何精确定位到源代码行列级别。

本文代码实现方式可能有些会造成性能问题,但是不必担心,后续也都会优化掉。