首先關於VsCode插件通信,如果不明白的可以參考我的這篇博客VsCode插件開發之插件初步通信
如果需要詳細例子的話,可以參考VsCode插件開發
現在又有一個新的需求是,VsCode插件可以通過jQuery的方式/或者引入某種前端通信框架實現與后台交互。但是針對之前某個需求,需求描述:用戶登錄后在本地某盤創建特定的文件夾。通常像創建特定文件夾的話,一般都是后端語言實現。而我當時編寫的這個插件是用JavaScript,JavaScript是不能讀寫文件的,當然了,有些朋友可能會說可以使用ActiveXObject,但是這個ActiveXObject有局限性,它僅僅只能支持IE瀏覽器,而不能支持像Google Chrome和火狐這樣的通用性廣的瀏覽器。
為了解決這個需求,我決定結合node.js解決這個問題。
首先明確一點,vscode插件開發,不管是使用JavaScript還是TypeScript,通常由於本地調試的需求,都需要安裝對應庫,而管理這個庫,通常使用npm或yarn。由此我們便可知,我們直接可以在該插件中編寫node.js相關的代碼。
實現需求的步驟如下:
引入vscode相關的庫(因為要調用消息傳遞命令)
const testMode = false; // 為true時可以在瀏覽器打開不報錯 // vscode webview 網頁和普通網頁的唯一區別:多了一個acquireVsCodeApi方法 const vscode = testMode ? {} : acquireVsCodeApi(); const callbacks = {}; /** * 調用vscode原生api * @param data 可以是類似 {cmd: 'xxx', param1: 'xxx'},也可以直接是 cmd 字符串 * @param cb 可選的回調函數 */ function callVscode(data, cb) { if (typeof data === 'string') { data = { cmd: data }; } if (cb) { // 時間戳加上5位隨機數 const cbid = Date.now() + '' + Math.round(Math.random() * 100000); callbacks[cbid] = cb; data.cbid = cbid; } vscode.postMessage(data); }
消息傳到node.js
vscode.postMessage({ command: 'login', text: nickName });
那么有朋友會問,那么node.js是如何接收它的?
module.exports = function (context) { var interval = null; var i = 0; var flag = false; context.subscriptions.push(vscode.commands.registerCommand('extension.demo.showWelcome', function (uri) { if (flag) { return; } const panel = vscode.window.createWebviewPanel( 'testWelcome', // viewType "功能頁", // 視圖標題 vscode.ViewColumn.One, // 顯示在編輯器的哪個部位 { enableScripts: true, // 啟用JS,默認禁用 } ); flag = true; panel.onDidDispose( () => { flag = false; }, null, context.subscriptions); let global = { panel }; panel.webview.html = getWebViewContent(context, 'src/view/custom-welcome.html'); //創建文件 panel.webview.onDidReceiveMessage(message => { switch (message.command) { case 'login': create(message.text, true); break; case 'time': start(); break; case 'showCourseList': vscode.commands.executeCommand('extension.demo.showCourseList', message.text); break; case 'closeTime': stop(); break; case 'themeColor': var name = getTheme(); panel.webview.postMessage({ command: 'refactor', text: name }); break; case 'readToken': var name = getToken(); console.log("-------------go go go go go go go ------------------------:" + name); panel.webview.postMessage({ command: 'checkToken', text: name }); break; case 'storeUserId': console.log("----------------store UserId-----------------:" + message.text); storeUserId(message.text); break; case 'getUserId': var userId = getUserID(); console.log("----------------Get UserId-----------------:" + userId); panel.webview.postMessage({ command: 'readUserId', text: userId }); break; case 'storageToken': storeToken(message.text); break; case 'deleteToken': deleteToken(message.text); break; case 'readUploadFilePath': console.log("------------------------ readUploadFilePath -----------:" + message.text); var content = readExtensionFile(message.text); panel.webview.postMessage({ command: 'uploadConfig', text: content }); break; case 'downloadExtensionFile': downloadExtensionFile(message.text); break; } }, undefined, context.subscriptions); }));
通過message.command我們就可以獲取對應的command,根據command對應的字符走對應的case。這就是前端JavaScript與Node.js的通信。
Node.js如何響應JavaScript的通信(相當於打電話,我打電話給你,不能僅僅是我在說,也需要你的響應(回答))
Node.js響應JavaScript通信代碼如下(發送消息給window.addEventListener與前端JavaScript發送消息給Node.js本質上是一樣的)
switch (message.command) { case 'refactor': console.log("自定義背景顏色 custome background color:" + message.text); if (message.text == "light") { document.body.style.backgroundColor = "#FFFFFF"; } else { document.body.style.backgroundColor = "#333333"; } break; case 'checkToken': console.log("-------------------checkToken----------------------------:" + message.text); if (message.text == null || message.text == "") { Login() } else { $("#exit").show(); $("#settings-sync").show(); $("#upload_settings").show(); $("#token").val(message.text); readUploadFilePath("D://1024Workspace//extension//"); } break; case 'readUserId': console.log("=====================readUserID=========================:" + message.text); $("#userId").val(message.text); checkPermissions(message.text); break; case 'uploadConfig': console.log("========================Upload Config ======================:" + message.text); $("#uploadExtensionContent").val(message.text); break; } });
window.addEventListener在此相當於監聽全局。
通過message.text我們可以獲取node.js響應給前端JavaScript的文本消息或者是json數據。
上述說的兩點用官方的話語表示如下:
(1)JavaScript與Node.js通信;
(2)Node.js與JavaScript通信;