How to Embed VSCode Into a Browser with React

How to Embed VSCode Into a Browser with React

Learn how to embed VSCode into a browser with React. The editor for VSCode (monaco editor) is open source, and feels just like VSCode. The monaco editor can transpile TypeScript to JavaScript, we can run the JavaScript in the browser. By embedding the monaco editor in my web page I can explain TypeScript much better than any other website.

Image for post

https://github.com/Open-EdTech/react-run-code

Why I wanted a runnable VSCode clone

To explain why TypeScript is important, you need to explain why developer tooling is important. To explain why developer tooling is important you will need a code editing environment. Fortunately the editor for VSCode (monaco editor) is open source, and feels just like VSCode. By embedding the monaco editor in my web page I can explain TypeScript much better than any other website.

Plus, the monaco editor can transpile TypeScript to JavaScript, we can run the JavaScript in the browser and output the results for an interactive educational experience.

Running Code

By default, the monaco editor does not run code. It does syntax highlighting, auto-completion, red squiggly lines, hover information, etc. So how are we running code?

Basically we do this:

let userCode = 'console.log("hello world")'
try {
  Function(userCode)()
} catch (e) {
  console.log(e)
}

Running TypeScript

I’m pretty sure can’t just run TypeScript code like that, we need to run it as JavaScript. The monaco editor has a TypeScript compiler that it uses to check your TypeScript code. You can use that to emit the output from a single model, a model is basically just a file in VSCode.

const tsClient = await monacoInstance.languages.typescript
  .getTypeScriptWorker()
  .then((worker) => worker(typescriptModel.uri));
const emittedJS = (
  await tsClient.getEmitOutput(typescriptModel.uri.toString())

Then you take the emitted JavaScript and run it.

Building a Console

The console-feed react component was such a time saver (and it looks awesome!)

Image for post

This component reads from the console’s messages and outputs the formatting shown in the gif. We modified this component to clear the logs on each run to prevent logs from piling up endlessly.

Supporting Multiple Consoles

We want multiple editors per page, by default their consoles would all print the same message because we are just reading logs from the console. How do we isolate console messages by the editor that sent the message?

We make each editor output their unique editor ID as the last argument in an overridden console.log to distinguish between message sources.

let consoleOverride = `let console = (function (oldCons) {
  return {
    ...oldCons,
    log: function (...args) {
      args.push("${editorId}");
      oldCons.log.apply(oldCons, args);
    },
    warn: function (...args) {
      args.push("${editorId}");
      oldCons.warn.apply(oldCons, args);
    },
    error: function (...args) {
      args.push("${editorId}");
      oldCons.error.apply(oldCons, args);
    },
  };
})(window.console);`;
try {
  Function(consoleOverride + emittedJS)();
} catch (e) {
  ...

We only log the message to a console component if the last argument provided matched the ID of the console component.

Grading User Input

I had an idea that it might be useful to “grade” user code in a way that doesn’t involve any calls to any servers. The issue is that you will have a tough time calling an API from code that is running inside of Function(code)() . Also, since the grading process happens entirely on the client side there is no way to make the grading “unhackable”.

So we do something simple. If the message from the console is “Problem solved”, the problem is solved. By solved I mean that the owner of the website can use a callback function that executes custom logic when this message is logged.

Image for post

console.log(“Problem solved”) executes user defined function.

vscode javascript typescript react web-development

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

How native is React Native? | React Native vs Native App Development

Article covers: How native is react native?, React Native vs (Ionic, Cordova), Similarities and difference between React Native and Native App Development.

Make an App with React JS / JavaScript: React and TypeScript

Building a Web Application as a Front-End Developer using React JS and TypeScript! Learn how to use the “Thinking in React” method and apply it to your real web application. We will be using real live weather data to display in our application and make our components reusable and maintainable.

How to Migrate a React Component from JavaScript to TypeScript

Learn how to easily migrate a React component from JavaScript to TypeScript to improve your project. When migrating over to TypeScript, one basic thing to keep in mind is TypeScript files have a .ts extension instead of .js. Another thing to keep in mind that makes migrating over a breeze is that you can configure your TypeScript compiler to allow JavaScript files.

Top VSCode Extensions for React, React Native, JavaScript and Productivity

Bunch of VSCode Extensions that improve quality of your coding time no matter what stack you are using. In this post, you'll see Top VSCode Extensions for React, React Native, JavaScript and Productivity

Hire Dedicated React Native Developer

Have you ever thought of having your own app that runs smoothly over multiple platforms? React Native is an open-source cross-platform mobile application framework which is a great option to create mobile apps for both Android and iOS. **[Hire...