簡介:
通過點擊頁面的dom元素,來自動定位到源代碼位置。這樣可以快速讓一個剛接觸的項目熟悉代碼。在開發(fā)環(huán)境中也不會影響生產(chǎn)環(huán)境昭娩,具有輕量級影響小的特點泥兰。
效果預覽
垃圾簡書,動圖動不了题禀!
設計分析:
簡單來說客戶端就是我們的瀏覽器要監(jiān)聽點擊事件鞋诗,并向服務端發(fā)送請求打開vscode 源碼位置。服務端來接受瀏覽器發(fā)送的請求來打開對應的位置迈嘹。
1. 客戶端:
首先我們要獲取元素在代碼中的位置削彬,我們知道在webpack編譯的過程中可以使用loader來獲取源碼。我們只需要編寫一個匹配.vue
組件的loader就可以獲取templeate的元素
//loader.js
module.exports = function myloader(content,map,meta){
let conetlist = content.split('\n');
let res = []
const { resourcePath } = this
conetlist.forEach((item,index) => {
res.push(addLineAttr(item, index + 1, resourcePath))
});
return res.join('\n')
}
在webpack最新版本中可以直接在this中獲取相對應的文件位置秀仲。通過換行符切割融痛,索引位置可獲取對應的代碼行數(shù)。這樣我們就可以把每一行的元素對應的位置獲取到神僵。最后通過拼接給每個dom元素添加一個自定義的屬性來標識位置雁刷,如圖下所示。
function addLineAttr(line,index,resourcePath){
let path = process.cwd()
console.log('cwd',path,'__dirname',__dirname);
resourcePath = resourcePath.substring(path.length)
let reg = /<[\w-]+/g
let leftTagList = line.match(reg)
if (leftTagList) {
leftTagList = Array.from(new Set(leftTagList))
leftTagList.forEach(item => {
if (item && item.indexOf('template') == -1) {
let regx = new RegExp(`${item}`, 'g')
let location = `${item} code-location="${resourcePath}:${index}"`
line = line.replace(regx, location)
}
})
}
return line
}
最后在全局綁定一個事件來監(jiān)聽保礼,比如快捷鍵+點擊事件沛励。以免與原生click事件沖突,并向服務端發(fā)送請求
window.document.addEventListener('click',e=>{
let path = e.target.getAttribute('code-location'); //獲取路徑
fetch(`${localhost}:${port}/${api}?path=${path}`,{
method: 'get'
})
})
2.服務端:
服務端就比較簡單了,我們需要在項目中設置一個監(jiān)聽get請求的接口來處理炮障。我們知道在webpack的項目中會啟動一個webpack-dev-server的服務目派,我們可以在這個服務上添加一個我們需要的。這里我們可以直接掛載在它before的hooks上胁赢,
devServer:{
onBeforeSetupMiddleware:(devserver)=>{
if (!devserver) {
throw new Error('webpack-dev-server is not defined');
}
devserver.app.get('/api/path', function (req, res) {
res.json({ custom: 'response' });
let data = req.query.path
openedit(data)
});
}
},
但是這個在最新版本中已經(jīng)找不到了企蹭。通過查看官網(wǎng)文檔發(fā)現(xiàn)現(xiàn)在用的是onBeforeSetupMiddleware
3.通過命令打開文件
在vscode中我們可以通過命令來進行一些相關的操作,比如code -g
可以打開文檔相對應的路徑智末,具體命令可以查看網(wǎng)上資料.
const child_process = require('child_process')
module.exports = function (path) {
const res = process.cwd()+path
child_process.exec(`code -r -g ${res}`)
}
4.引入
至此所有的邏輯就完了谅摄,其實很簡單,主要的就是在loader中根據(jù)規(guī)則給dom元素添加上對應位置的屬性系馆,然后通過code命令來打開文件位置
我們只需要在vue.config.js中配置我們寫好的loader就可以送漠。
module:{
rules:[
{
test:/\.vue$/,
use:[
{
loader:path.join(__dirname,'@open-vs-link/myloader.js'),
options:{ }
}
],
}
]
}
最后補充,vite項目也是同樣的道理它呀,只是區(qū)分不同的掛載時期和引入方式螺男。react項目也是同理棒厘。最后有時間可以封裝好給團隊的小伙伴使用o.O