VsCode插件與Node.js交互通信


首先關於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通信;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM