背景:由于中臺(tái)項(xiàng)目頁面繁多造垛,文件夾繁多,開發(fā)人員每次修改頁面都要根據(jù)路由路徑去找對(duì)應(yīng)的源代碼羞秤,所以鞠抑,有沒有一種方法,可以直接在開發(fā)環(huán)境運(yùn)行的頁面里面直接定位到vscode源代碼
原理:通過vscode protocal 協(xié)議方式(vscode://file/文件路徑:行號(hào))嫌吠,去喚起vscode查看源文件了止潘。
1、以vue-admin-template為例子
# clone the project
git clone https://github.com/PanJiaChen/vue-admin-template.git
# enter the project directory
cd vue-admin-template
# install dependency
npm install
# develop
npm run dev
2辫诅、安裝插件webpack-virtual-modules
npm i webpack-virtual-modules -D
3凭戴、修改vue.config.js文件
// vue.config.js
// 添加以下代碼
// 借助webpack-virtual-modules生成虛擬模塊
const VirtualModulesPlugin = require('webpack-virtual-modules')
configureWebpack: config => {
const plugins = []
if (process.env.NODE_ENV === 'development') {
plugins.push(
/** 創(chuàng)建虛擬模塊 */
new VirtualModulesPlugin({
'node_modules/virtual-module-cwd.js': `module.exports = "${process.cwd().replace(/\\/g, '/')}"`
})
)
}
config.plugins = [...config.plugins, ...plugins]
}
4、在src/utils/
文件夾下創(chuàng)建文件vscodeRouterFile.js
炕矮,內(nèi)容如下:
const cwd = require("virtual-module-cwd");
export default {
install(Vue, options = {}) {
const { style = {}, innerHTML = "" } = options;
function createDom(path) {
const domId = "vscode_router_file_element";
let dom = document.querySelector(`#${domId}`);
if (!dom) {
dom = document.createElement("div");
dom.id = domId;
Object.assign(
dom.style,
{
position: "fixed",
fontWeight: "bold",
top: "200px",
right: "50px",
zIndex: 10000,
cursor: "move",
width: "70px",
height: "70px",
borderRadius: "50%",
lineHeight: "70px",
textAlign: "center",
fontSize: "14px",
color: "rgb(255, 255, 255)",
userSelect: "none",
backgroundImage: "linear-gradient(to right, red,orange,yellow,green,blue,indigo,violet)"
},
style
);
dom.innerHTML = innerHTML || "打開源碼";
document.body.appendChild(dom);
dragDom(dom);
}
dom.ondblclick = function () {
window.open(`vscode://file/${cwd}/${path}:0`);
};
}
function dragDom(dom) {
let x = 0;
let y = 0;
let l = 0;
let t = 0;
let isDown = false;
dom.onmousedown = function (e) {
x = e.clientX;
y = e.clientY;
l = dom.offsetLeft;
t = dom.offsetTop;
isDown = true;
dom.style.cursor = "move";
};
window.onmousemove = function (e) {
if (isDown === false) return;
const nx = e.clientX;
const ny = e.clientY;
const nl = nx - (x - l);
const nt = ny - (y - t);
dom.style.left = nl + "px";
dom.style.top = nt + "px";
};
dom.onmouseup = function () {
isDown = false;
dom.style.cursor = "default";
};
}
Vue.mixin({
beforeRouteEnter(to, from, next) {
next((vm) => {
const routerCom = to.matched[to.matched.length-1];
if(!routerCom) return
routerCom && createDom(routerCom.components.default.__file);
});
},
});
},
};
5么夫、在mian.js
里面引用
/** 開發(fā)環(huán)境引入vscodeRouterFile */
import vscodeRouterFile from "@/utils/vscodeRouterFile"
if(process.env.NODE_ENV === 'development') {
Vue.use(vscodeRouterFile)
}
6、運(yùn)行項(xiàng)目肤视,會(huì)出現(xiàn)打開源碼
的按鈕档痪,雙擊
可跳轉(zhuǎn)到對(duì)應(yīng)的路由源文件
7、缺點(diǎn)
- 如果vscode有多個(gè)實(shí)例(窗口)在運(yùn)行邢滑,文件會(huì)在焦點(diǎn)實(shí)例(窗口)里面打開腐螟,建議只開啟一個(gè)vscode實(shí)例(窗口)
8、參考資料
https://juejin.cn/post/6960480138525933599
9困后、由于并沒有引入virtual-module-cwd模塊乐纸,導(dǎo)致打包c(diǎn)onst cwd = require("virtual-module-cwd")報(bào)錯(cuò)失敗,以下為修改后的最新代碼
原理:由于webpack設(shè)置了開發(fā)環(huán)境才生成虛擬模塊摇予,在打包時(shí)沒有虛擬模塊锯仪,當(dāng)前代碼const cwd = require("virtual-module-cwd")
引入失敗,由于es6模塊
加載不能在代碼塊里面引用趾盐,所以改為node模塊
引用庶喜,這樣就可以先判斷當(dāng)前運(yùn)行環(huán)境小腊,再引入vscodeRouterFile代碼
// main.js
/** 用于vscode根據(jù)路由定位源文件 */
if (process.env.NODE_ENV === 'development') {
const { install } = require('../vscodeRouterFile')
Vue.use({install})
}
// vscodeRouterFile\index.js
const cwd = require("virtual-module-cwd");
export function install(Vue, options = {}) {
const { style = {}, innerHTML = "" } = options;
function createDom(path) {
const domId = "vscode_router_file_element";
let dom = document.querySelector(`#${domId}`);
if (!dom) {
dom = document.createElement("div");
dom.id = domId;
Object.assign(
dom.style,
{
position: "fixed",
fontWeight: "bold",
top: "200px",
right: "50px",
zIndex: 10000,
cursor: "move",
width: "70px",
height: "70px",
borderRadius: "50%",
lineHeight: "70px",
textAlign: "center",
fontSize: "14px",
color: "rgb(255, 255, 255)",
userSelect: "none",
background: "lightgray",
textShadow: "4px 4px 4px #000000"
},
style
);
dom.innerHTML = innerHTML || "打開源碼";
document.body.appendChild(dom);
dragDom(dom);
}
dom.ondblclick = function () {
window.open(`vscode://file/${cwd}/${path}:0`);
};
}
function dragDom(dom) {
let x = 0;
let y = 0;
let l = 0;
let t = 0;
let isDown = false;
dom.onmousedown = function (e) {
x = e.clientX;
y = e.clientY;
l = dom.offsetLeft;
t = dom.offsetTop;
isDown = true;
dom.style.cursor = "move";
};
window.onmousemove = function (e) {
if (isDown === false) return;
const nx = e.clientX;
const ny = e.clientY;
const nl = nx - (x - l);
const nt = ny - (y - t);
dom.style.left = nl + "px";
dom.style.top = nt + "px";
};
dom.onmouseup = function () {
isDown = false;
dom.style.cursor = "default";
};
}
Vue.mixin({
beforeRouteEnter(to, from, next) {
next(async (vm) => {
const routerCom = to.matched[to.matched.length - 1];
if (!routerCom) return
routerCom && createDom(routerCom.components.default.__file);
});
},
});
}