前段時(shí)間步藕,公司學(xué)習(xí)小組起建了一個(gè)項(xiàng)目:開(kāi)發(fā)VSCode的插件锐借。
前期研究方案發(fā)現(xiàn)VSCode是基于Electron開(kāi)發(fā)的火欧,所以首要研究的技術(shù)是Electron和VSCode Extension的相關(guān)API弛槐。本人之前沒(méi)有任何使用VSCode的經(jīng)驗(yàn),前端開(kāi)發(fā)目前更多接觸Vue.js署驻。基于學(xué)習(xí)交流的前提下健霹,小組成員一致同意使用Electron+Vue.js的方案旺上,學(xué)習(xí)目標(biāo)也定在這兩個(gè)前端框架上。(至于這兩個(gè)框架是什么糖埋,大家可以自行Google)
技術(shù)思路
經(jīng)研究發(fā)現(xiàn)宣吱,VSCode-Extension-API已經(jīng)足夠開(kāi)發(fā)本次項(xiàng)目的需求,無(wú)需接入Electron API瞳别,項(xiàng)目的主要UI實(shí)現(xiàn)都是基于Vue.js(由于目前的項(xiàng)目是二次開(kāi)發(fā)征候,可以使用許多原有的js文件钦听,使用Electron重寫(xiě)不太顯現(xiàn)實(shí),所以考慮用Vue來(lái)寫(xiě)部分頁(yè)面倍奢,然后接入其他部分已有的文件)朴上,當(dāng)然你也可以考慮只是使用Electron去開(kāi)發(fā)。
本項(xiàng)目中創(chuàng)建了兩個(gè)工程卒煞,一個(gè)是VSCode插件工程痪宰,另一個(gè)是Vue項(xiàng)目工程,其中Vue工程嵌入在VSCode插件工程中畔裕,然后使用VSCode的webview加載Vue構(gòu)建的js文件衣撬。
踩坑一:VSCode Webview無(wú)法加載相對(duì)路徑文件
VSCode Webview只支持加載遵循vscode-resource協(xié)議的文件,但Vue使用webpack打包出來(lái)index.html文件中扮饶,引入js或css文件的路徑是相對(duì)路徑具练,我們需要進(jìn)行修改,當(dāng)然你可以手動(dòng)去修改甜无,但是考慮到每次build之后都要手動(dòng)去更改的話扛点,效率是非常低的。所以我們?cè)谧x取index.html文件的內(nèi)容之后岂丘,進(jìn)行路徑替換陵究,代碼如下:
function getWebContent(context:vscode.ExtensionContext,uri:string){
const rootPath = context.extensionPath;
const abPath = path.join(rootPath,uri);
const dirPath = path.dirname(abPath);
var html = fs.readFileSync(abPath,'utf-8');
// vscode不支持直接加載本地資源,需要替換成其專(zhuān)有路徑格式奥帘,這里只是簡(jiǎn)單的將樣式和JS的路徑替換
html = html.replace(/(href=\.|src=\.)/g, function(m, ops, orgin){
//這里去除后綴. 铜邮,然后再合并絕對(duì)路徑,記得使用vscode-resource scheme
const path = m.substring(0,m.length-1) +vscode.Uri.file(dirPath).with({ scheme: 'vscode-resource' }).toString();
return path;
});
console.log(html);
return html;
}
踩坑二:.CSS文件的樣式無(wú)法正常加載
Vue打包出來(lái)的CSS文件在VSCode中的Webview中可能無(wú)法顯示(低版本VSCode中有問(wèn)題)寨蹋,在VSCode中調(diào)試網(wǎng)頁(yè)(在插件命令中打開(kāi)松蒜,不是F12),發(fā)現(xiàn)CSS文件是已經(jīng)正確加載了的已旧。當(dāng)你遇到這個(gè)問(wèn)題的時(shí)候秸苗,建議你直接把CSS代碼拷貝過(guò)來(lái),粘貼到index.html中评姨。目前尚未查明原因难述。
踩坑三:不能使用acquireVsCodeApi()返回局部vscode實(shí)例
由于需要Vue的實(shí)例能與VSCode的webview通信,在VSCode Extension API中提供了專(zhuān)用的全局vscode實(shí)例吐句,也就是通過(guò)js函數(shù)acquireVsCodeApi()返回胁后。所以你需要在Vue將acquireVsCodeApi()返回的實(shí)例設(shè)為全局變量,避免重復(fù)生成而報(bào)錯(cuò)嗦枢。
踩坑四:不能直接通過(guò)import方法將厚重的js文件引進(jìn)到Vue中
項(xiàng)目由于需要引進(jìn)一些之前的js文件攀芯,而這些js文件是由webpack打包出來(lái)的,假如在vue中直接通過(guò)import加載這些js文件文虏,會(huì)提示js體積過(guò)大(大于500kb)侣诺,構(gòu)建過(guò)程失敗殖演。此時(shí)你需要使用webpack 的 extenals 擴(kuò)展技術(shù)引入這些無(wú)需打包的文件,代碼如下:
假設(shè)你有個(gè)a.js的文件年鸳,export為 export_xxx趴久,你需要將這個(gè)文件拖到vue工程下的static路徑中,然后webpack會(huì)在構(gòu)建中在index.html中自動(dòng)引入這個(gè)文件搔确。你需要在webpack.dev.config.js和webpack.prod.config.js中加入
output: {
#瀏覽器中使用
libraryTarget: "umd"
},
externals:{
'vue_instance': 'export_xxxx'
},
如果你想引用這個(gè)文件的內(nèi)容彼棍,你需要在使用過(guò)的地方加入
import $ from vue_instance