Ruby, Rails, and Javascript Editing With Visual Studio Code

I’ve been using Vim as my main editor for a while now, but after recently pairing with someone at work that used Visual Studio Code, I decided to check it out.

It’s an excellent, powerful, and free editor that most people will love. Here are my thoughts on it, including a guide on setting it up for Ruby, Rails, and Javascript development.

Overview

Visual Studio Code is an excellent code editor with powerful in built concepts and a wonderful ecosystem of external extensions.

I see it as an editor that allows new and experienced programmers alike to be more productive.

Personally, over the last month of using it daily at work and for my side projects, I’ve really enjoyed it; so much so that I’ve decided to write up this blog post to detail how you can get up and running with it yourself.

Installation

You can install Visual Studio Code by visiting its official website. On the homepage, there should be a large CTA prompting you to download and install the correct version for your operating system.

If you’re on a Mac, you can also use Homebrew Cask to install Visual Studio Code by running brew cask install visual-studio-code in your terminal. This is particularly useful if you automate the configuration of your development environment.

Extensions

Once installed, Visual Studio Code is very powerful out of the box. One of the best features is extensions – a way to extend the editor with powerful external plugins.

Open the extensions menu by selecting View -> Extensions or the shortcut (for macOS) Shift+Command+X.

To install an extension, click the Install button, either on the extension snippet in the left sidebar, or on the main extension page.

Visual Studio Code will install the extension and prompt you to reload the editor if necessary. Don’t worry if you have current work in progress in your editor, Visual Studio Code will restore your editor to the exact state it was (with the new extension installed) after you reload.

Ruby

The Ruby extension provides Ruby language and debugging support for Visual Studio Code. It’s an important extension that enables debugging, linting, formatting, autocomplete, and Intellisense support (native “Go to Definition, “Peek”, and “Symbol listing”).

I recommend setting up linting and formatting, with autocomplete and Intellisense being optional nice-to-haves.

Javascript

Visual Studio Code is built using web technologies. Microsoft – who created Visual Studio Code – has ensured that support for modern Javascript, and Typescript (which they also created) is fully-featured out of the box.

Visual Studio Code works very well with existing vanilla Javascript and TypeScript, as well as popular frameworks such as React, Angular, and Ember. VueJS is also supported, however it needs an extra extension to enable Intellisense, snippets, and formatting.

Snippets

Like most other modern editors, Visual Studio Code has support for snippets. I recommend reading about and understanding the concepts, and writing your own to reduce boilerplate.

Useful snippets include creating classes, functions, variables, and constructs (such as loops and conditional expressions).

Be aware that extensions may install snippets, so make sure you’re not duplicating work as installed extension has done for you.

Multi-cursor editing

Multiple cursor editing has been the largest revelation in editing code using Visual Studio Code in comparison to Vim. It’s a fantastic way to quickly manipulate text, and while I’m aware that the concept has been around for a while, I had never tried it until I tried Visual Studio Code.

I recommend reading about multiple cursor support and trying it out for yourself if you haven’t already. Learning shortcuts such as Command+D has proven to be a huge productivity boost.

Integrated Terminal

Like Neovim, Visual Studio Code comes with an integrated terminal. It’s very useful when you want to run simple commands, such as ls, grep, etc. without leaving your editor.

For anything more complex, I still prefer to use a full terminal emulator like Terminal or iTerm2 (macOS).

Debugging with Ruby on Rails and React JS

To demonstrate the power of Visual Studio Code’s debugging ability, I am going to show you how to debug on the server and client side.

For this to work, you need the following extensions installed:

You need the following gems installed globally:

  • ruby-debug-ide
  • debase

You need to be using rbenv and ruby-build to manage your ruby dependencies if you’re following this guide exactly.

Open your project and head to the debug view (View -> Debug) , click the gear icon. Select Ruby and select the Debug Local File option.

Open the .vscode/launch.json file and replace it with the following:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Rails: Start server",
      "type": "Ruby",
      "request": "launch",
      "cwd": "${workspaceRoot}",
      "program": "${workspaceRoot}/bin/rails",
      "args": [
        "server",
        "-p",
        "3000"
      ]
    },
    {
      "name": "Rails: Attach to server",
      "type": "Ruby",
      "request": "attach",
      "cwd": "${workspaceRoot}",
      "remoteWorkspaceRoot": "${workspaceRoot}",
      "remoteHost": "127.0.0.1",
      "remotePort": "9567"
    },
    {
      "name": "RSpec: Run all specs",
      "type": "Ruby",
      "request": "launch",
      "cwd": "${workspaceRoot}",
      "program": "${workspaceRoot}/bin/rspec",
      "args": [
        "-I",
        "${workspaceRoot}"
      ]
    },
    {
      "name": "RSpec: Active spec file only",
      "type": "Ruby",
      "request": "launch",
      "cwd": "${workspaceRoot}",
      "program": "${workspaceRoot}/bin/rspec",
      "args": [
        "-I",
        "${workspaceRoot}",
        "${file}"
      ]
    },
    {
      "name": "RSpec: Active spec at current line",
      "type": "Ruby",
      "request": "launch",
      "cwd": "${workspaceRoot}",
      "program": "${workspaceRoot}/bin/rspec",
      "args": [
        "-I",
        "${workspaceRoot}",
        "${file}:${lineNumber}"
      ]
    },
    {
      "name": "React: Attach to chrome",
      "type": "chrome",
      "request": "attach",
      "port": 9222,
      "url": "http://localhost:3000/",
      "webRoot": "${workspaceFolder}"
    }
  ]
}

Rails: Start server

This configuration launches a rails server which can be debugged at any time by setting a breakpoint in the editor.

This is similar to if you had run bin/rails s from your terminal (without the breakpoint capability)

Rails: Attach to server

This configuration attaches to an existing instance of a rails server that was started by ruby-debug-ide, e.g.

rdebug-ide --host 127.0.0.1 \
    	   --port 9567 \
           -- bin/rails s

Once you’ve attached to the running server instance, you can use breakpoints the same way as if you had started launched the server from Visual Studio Code itself.

Note: even after executing the above ruby-debug-ide command, the server will not run until you have attached to it.

Furthermore, if you detach from the server, it’ll stop running.

RSpec

There are three configurations for debugging specs that correspond to:

  • running an entire suite.
  • running an individual file
  • running an individual spec (using the cursor position as the marker) Set a break point before running any of the commands, and it’ll stop once the line of code is hit.

React: Attach to chrome

You can attach to an existing Chrome instance and use Visual Studio Code breakpoints instead of Chrome breakpoints. This, in my personal opinion, is a much superior way to debug any front-end applications.

In order to do this, you need to run Chrome with the remote debugging protocol flag, e.g.

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222

Make sure to close (quit) all existing instances of Chrome before running the above command.

Once Chrome is running, visit localhost:3000 and you can select the React: Attach to chrome debug option in Visual Studio Code to attach to the running instance of Chrome.

Note: if your breakpoints aren’t being triggered, it’s most likely your source map settings. The remote debugging protocol uses source maps to identify which files on the server correspond to the files in your editor. I had to add the following option to the React: Attach to chrome configuration object to the setup at work setup hit breakpoints.

"sourceMapPathOverrides": {
  "webpack:///app/assets/*": "${webRoot}/app/assets/*"
}

A programming blog exploring the code, tools, and techniques behind high quality software.

© 2020 Muyiwa Olu ·