DEV Community

Cover image for VSCode: Escaping WebView iframe
hellowwworld
hellowwworld

Posted on

VSCode: Escaping WebView iframe

When developing extensions for VSCode using a favored frontend framework like React, Svelte, or Vue.js, a common hurdle encountered is the communication between the VSCode environment and the WebView where your app is rendered. Traditionally, acquireVsCodeApi() is employed to facilitate this, but it becomes undefined once you start using iframe with URL as src, bringing the postMessage API out of reach and crippling the interaction.

In light of this, you could use a strategy that turns extension.ts into a Socket.io server while WebView leverages a locally running React app with a Socket.io client, fostering real-time bi-directional event-based communication.

Setting the Stage

Your extension.ts would take on the role of a Socket.io server, initiating a pathway for continuous communication. Parallelly, the WebView would harbor a React application tuned to be a client for the Socket.io server.

Establishing the Connection

VSCode Extension Side

First, install the necessary socket.io package in your extension project:

$ npm install socket.io
Enter fullscreen mode Exit fullscreen mode

Next, in your extension.ts file, initialize the socket.io server:

import { createServer } from "http";
import { Server } from "socket.io";

const httpServer = createServer();
const io = new Server(httpServer);
io.on("connection", (socket) => {
  console.log("New client connected");

  // Listen for messages from the client
  socket.on("messageFromClient", (msg) => {
    console.log("Received message from client:", msg);
  });

  // Sending a welcome message to the client
  socket.emit("messageFromServer", { data: "Hello, client!" });
});
Enter fullscreen mode Exit fullscreen mode

React App Side

Install socket.io-client in your React project:

$ npm install socket.io-client
Enter fullscreen mode Exit fullscreen mode

In your main React component, initialize the socket.io client and set up event listeners to communicate with the server:

import { useEffect } from "react";
import { io } from "socket.io-client";

// port can be passed as a query parameter
const port = new URLSearchParams(window.location.search).get('port')
const socket =  io(`http://localhost:${port}`);

function App() {
  useEffect(() => {
    // Listen for messages from the server
    socket.on("messageFromServer", (msg) => {
      console.log("Received message from server:", msg);
    });

    // Sending a message to the server
    socket.emit("messageFromClient", { data: "Hello, server!" });
  }, []);

  return <div className="App">Socket.io with VSCode</div>;
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Securing the Communication

Leveraging socket.io for real-time communication opens up a new dimension of interaction between VSCode and WebView, but it comes with its share of security concerns. Securing the data transmitted over the socket is crucial to safeguard sensitive information and maintain user trust.

Conclusion

This communication pathway between extension.ts and a frontend app within WebView, championed by socket.io, promises a rich, real-time bi-directional communication unhindered by the traditional restrictions of VSCode's WebView iframe.

Please share your perspectives and join in refining this architectural blueprint.

Top comments (0)