背景: 前端开发同学在工作时需要通过浏览器查看页面
DOM
对应的组件位置信息,很多时候我们都是找到对应的className
或者文字关键字去vscode
搜索,进而找到需要改动的组件位置信息。在react 项目已经有 点击页面元素 唤起 IDE, 点击这里直达文章。 本文介绍Vue2 项目如何开启同样的功能。
你是否遇到以下的一些问题:
- 前端开发同学在工作时需要通过浏览器查看页面DOM对应的组件位置信息,很多时候我们都是找到对应的
className
或者文字关键字去vscode
搜索,进而找到需要改动的组件位置信息 - 开启该插件,可以在控制面板快速查看该
DOM
对应的组件信息 (组件名字 & 当前DOM
行列信息) - 或者一个同学突然接到一个新需求,要求去改不熟悉的代码,此时这位同学就会通过
className
或者文字关键字去vscode
搜索,进而找到需要改动的组件位置信息 - 通过关键字去
vscode
搜索找到信息,有时候可能会搜到多处,我们会搞不清到底哪一处是我们需要改的 - 现在通过编译时,对
react
项目 进行ast
注入,会在渲染时携带该DOM
的位置信息 (包括组件所在的 位置,该DOM
所在的行信息) - 以下配置只限于在
dev
环境开启 (prod
开启问题也不大,就是显得不太专业,就像sorcemap
暴露出去意义,显得不专业) - 开启下面配置之后,在浏览器找到对应需要修改的
DOM
,复制其位置,在vscode
使用command + p
直接 粘贴进去,找到对应的位置即可修改。
需要使用到的 npm
包有2个,分别是 cus-utils
webpack-plugin-forceinsertscripttag
(其中 webpack-plugin-forceinsertscripttag
依赖于 html-webpack-plugin
version 5
版本,如果项目中没有用到html-webpack-plugin
, 建议使用另一个包 webpack-plugin-addscriptforhtmlplugin
,两者参数一致,在不同的场景使用拥有不同的选择 )
webpack-plugin-forceinsertscripttag
仓库链接
cus-utils
preTransformNode.ts 文件仓库链接
效果:
- 开启成功在控制台有如下图的提示
-
webpack-plugin-forceinsertscripttag
包的功能是: 在webpack
打包阶段 调用html-webpack-plugin
的afterTemplateExecution
钩子去插入一段script
,被插入的script
就是唤起 IDE 的script
。 (webpack-plugin-forceinse``rtscripttag
可在 编译阶段 插入任意一段script
, 欢迎大家在业务中使用) 仓库地址。 此插件基于~~~~html-webpack-plugin
~~~~ 实现的,所以你的项目如果没有使用 、~~~~html-webpack-plugin
~~~~ ,接入此插件不会按照预期工作,最近我会在写一个插件弥补这部分工作 (已经完成了, 新的webpack
插件:webpack-plugin-addscriptforhtmlplugin
, 此插件不依赖任何webpack
插件,功能和webpack-plugin-forceinsertscripttag
一致 ) -
cus-utils
包的功能是: 在编译.vue
文件的时候,拿到AST
进而拿到 文件信息,进行AST
注入。(这里抛出一个问题, 为什么react
项目可以借助babel
插件进行AST
劫持,Vue
项目就不可以呢?)。核心功能在cus-utils
的preTransformNode.ts
文件里面,主要是 通过劫持preTransformNode
方法完成的AST
操作。 (此包是整个功能的核心) -
cus-utils
的preTransformNode.ts
文件的preTransformNodeList
函数有两个参数,两个都不是必传的 (preTransformNodeList({isShowRelativerPath: true, projectRootPath: process.cwd()})
, 参数1:isShowRelativerPath
表示是否展示 组件的相当于 根目录的相对路径,参数2: 表示 当前项目的跟路径。 两个参数都可以不传)
如何配置: 场景1 -> 这里的配置 适合整个团队统一使用同一个ide
的情况
- 如何使用
- 首先安装
cus-utils 、webpack-plugin-forceinsertscripttag
npm i cus-utils webpack-plugin-forceinsertscripttag -D
3. 在 vue.config.js
配置(只在dev
开启这个插件即可)
// vue.config.js
const webpackPluginForceinsertscriptTag = require("webpack-plugin-forceinsertscripttag");
const { preTransformNodeList } = require('cus-utils')
// 注意 在 dev 模式开启该系列插件
module.exports = defineConfig({
...
chainWebpack: (config) => {
// 针对 .vue 文件的 vue-loader 配置进行修改
// 下面的配置默认打开的 vscode IDE
if(isDev){
config.plugin("webpackPluginForceinsertscriptTag").use(
new webpackPluginForceinsertscriptTag({
isShift: false,
isInsertBody: true,
jsDeferLoad: false,
jsAsyncLoad: false,
isLaunchIdeJs: true,
})
);
}
config.module
.rule("vue")
.use("vue-loader")
.tap((options) => {
// 扩展 vue-loader 的 options 来传递给其内部的 babel-loader
return {
...options,
compilerOptions: {
modules: isDev ? preTransformNodeList() : []
},
};
});
},
});
假设 团队有人用 vscode
有人用webstorm
,那么 这个 webpackPluginForceinsertscriptTag
的ideName
配置项 就需要定制化改动 , 那么改动的人还不能提交 webpack.config.js
因为会影响别人使用(下面提供千人千面的配置场景)
如何配置: 场景2 -> 这里的配置 适合整个团队没有统一使用同一个ide
的情况
- 如何使用配置千人千面配置开发
- 首先安装
cus-utils 、webpack-plugin-forceinsertscripttag
npm i cus-utils webpack-plugin-forceinsertscripttag -D
4. 在 vue.config.js
配置略有不同
// vue.config.js
const webpackPluginForceinsertscriptTag = require("webpack-plugin-forceinsertscripttag");
const { preTransformNodeList } = require('cus-utils')
/****** 定制化配置 (默认 ide 是 vscode, 这里千人千面 可以变更为 自己使用的 ide),会被 webpack-plugin-forceinsertscripttag 合并 ******/
let ignoreConfigPath = path.resolve(__dirname, "./ignore.config.js");
const isExitIgnoreConfigFile = fs.existsSync(ignoreConfigPath);
const ignoreConfig = isExitIgnoreConfigFile ? require(ignoreConfigPath) : {};
/****** 定制化配置 (默认 ide 是 vscode, 这里千人千面 可以变更为 自己使用的 ide),会被 webpack-plugin-forceinsertscripttag 合并 *****/
// 注意 在 dev 模式开启该系列插件
module.exports = defineConfig({
...
chainWebpack: (config) => {
// 针对 .vue 文件的 vue-loader 配置进行修改
// 下面的配置默认打开的 vscode IDE
if(isDev){
config.plugin("webpackPluginForceinsertscriptTag").use(
new webpackPluginForceinsertscriptTag({
isShift: false,
isInsertBody: true,
jsDeferLoad: false,
jsAsyncLoad: false,
isLaunchIdeJs: true,
...ignoreConfig,
})
);
}
config.module
.rule("vue")
.use("vue-loader")
.tap((options) => {
// 扩展 vue-loader 的 options 来传递给其内部的 babel-loader
return {
...options,
compilerOptions: {
modules: isDev ? preTransformNodeList() : []
},
};
});
},
});
5. 上面的核心配置就是支持了千人千面的 IDE
配置,维护一个 ignore.config.js
, 里面存放唤起的 IDE
配置,这个ignore.config.js
放到 .gitignore
文件里面去 (ideName: 用户的ide名字, userGetUrl: 自定义跳转逻辑,函数的入参数代表 文件的绝对路径, 函数的出参数代表 被 ide 唤起的协议 + 路径 + 行列)
// ignore.config.js
module.exports = {
ideName: "vscode",
// 这里的函数是自定义跳转逻辑,函数的入参数代表 文件的绝对路径, 函数的出参数代表 被 ide 唤起的协议 + 路径 + 行列 userGetUrl(completeFilepath) { return "vscode://file" + completeFilepath; },
userGetUrl(completeFilepath) {
return "vscode://file" + completeFilepath;
},
};
6. 核心: 通过维护 ignore.config.js
里面的 ideName
字段配置,达到千人千面开发配置
提供2种接入方式
- 第一种适合团队统一
ide
的情况 - 第二种适合团队定制化,千人千面配置的情况