Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Ubuntu

A Note on Visual Studio Code

5.00/5 (1 vote)
5 Nov 2019CPOL7 min read 6.7K   53  
FAQs about Visual Studio Code
This article provides a comprehensive guide on installing and using Visual Studio Code, including topics such as installation, setting up Node.js, working with folders and terminals, creating workspaces, using the debugger, and configuring VSC's behavior.

Introduction

This is a note on Visual Studio Code or simply VSC.

Background

In this note, I will try to cover the following most frequently asked questions (FAQs).

This note is prepared with a VM running Linux Mint 19.1 Cinnamon. The Linux Mint 19.1 Cinnamon is based on Ubuntu 18.04.

Install VSC and Node

Install VSC

According to the instruction, the easiest way to install VSC is to download the ".deb package (64-bit)" from this link and install it using the following command:

sudo apt install ./<file>.deb

Alternatively, we can also add the Microsoft repository manually.

curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo install -o root -g root -m 644 microsoft.gpg /etc/apt/trusted.gpg.d/
sudo sh -c 'echo "deb [arch=amd64] 
https://packages.microsoft.com/repos/vscode stable main" > /etc/apt/sources.list.d/vscode.list'

With the repository added, we can use the following commands to install VSC.

sudo apt-get install apt-transport-https
sudo apt-get update
apt-cache policy code
sudo apt-get install code

If we want, we can also choose a specific version of VSC to install.

sudo apt-get install code=1.33.0-1554390824

Upon successful installation, we can look for "vsc" to launch VSC.

Image 1

The default color theme comes with a black background.

Image 2

Because I do not like the black background, I changed it to the white background.

Image 3

Install Node and NPM

There are many ways to install Node and NPM, but I chose a simple way by directly downloading it from https://nodejs.org/en/. By the time I downloaded it, I got the version "node-v10.16.0-linux-x64.tar.xz". For simplicity, I just decompressed it into a folder under my home directory.

Image 4

The executables of Node and NPM are in the bin folder, so I add the following lines in my .profile file, which makes sure that the node-v10.16.0-linux-x64/bin folder is added into my executable search path.

PATH=".:$PATH"
PATH="/home/song/Development/node/node-v10.16.0-linux-x64/bin:$PATH"

If you are not familiar with NPM, the following are a few commonly used NPM commands:

npm -v
npm view -h
npm view npm
npm install -g npm@6.9.2
npm install -g npm
npm root -g

Image 5

Work on a Folder & ".vscode" & the Command Terminal

Although VSC chose not to call it the same way, a root level folder in VSC is virtually equivalent to a project in other IDEs, such as Eclipse. Now that we have both VSC and Node ready, we can create a small Node example in VSC. In this example, we will get some hands-on experience on the ".vscode" folder and the command terminal.

cd ~
mkdir -p Sandbox/vsc-example/simple-node-api

After creating the "simple-node-api" folder, from menu "File" -> "Open Folder ..." to open the simple-node-api folder.

Image 6

For this example, we just need to add the "package.json" file and the "app.js" file.

JavaScript
{
  "name": "simple-node-example",
  "version": "0.0.1",
  "private": true,
  "dependencies": {
    "express": "4.16.4",
    "errorhandler": "1.5.1",
    "cors": "2.8.5"
  }
}

We will expose a GET API that responds with a JSON object that has the current time.

JavaScript
let express = require('express'),
    http = require('http'),
    cors = require('cors'),
    errorhandler = require('errorhandler');
    
let app = express();
app.set('port', 3000);
    
app.use(function (req, res, next) {
  res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
  res.header('Expires', '-1');
  res.header('Pragma', 'no-cache');
  next();
});
    
app.use(cors());
    
app.get('/time', function (req, res) {
  let d = new Date();
  res.send({ time: d.toLocaleTimeString() });
})
    
app.use(errorhandler());
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

The ".vscode" Directory

In VSC, we can configure how VSC manages the folder by the files in the .vscode folder. In this example, I placed the file settings.json in the .vscode folder.

JavaScript
{
    "files.exclude": {
        "**/package-lock.json": true,
        "**/.git": true,
        "**/.DS_Store": true,
        "**/node_modules": true,
        ".vscode": true
    }   
}

I explicitly instructed VSC to ignore the node_modules folder, because it is simply too large for VSC to handle. In VSC, we can add many more configuration options. In a later section, I will show you how to add debug configurations in the .vscode folder.

The Terminal

Another convenient tool in VSC is the command terminal. It allows us to issue shell commands without leaving VSC. We can use CTL+'`' to toggle the visibility of the terminal and use CTL+SFT+'`' to add additional panel to the terminal.

Image 7

With the terminal open, we can issue the following commands to install the node_modules and to run the application.

npm install
node app.js

If we go to http://localhost:3000/time in the browser, we can see the JSON response from the node application.

Image 8

Workspace & Multiple Root Level Folders

While it is possible to work on a folder (or project that VSC chose not to call it such way), it is necessary to work on multiple folders in many cases. In VSC, the terminology workspace is introduced to group multiple folders. In Eclipse IDE, the same mechanism is also called workspace. To convert the simple-node-api folder to a workspace, we can click File -> Save Workspace As... to open the Save Workspace dialog window.

Image 9

A workspace file is just a file with .code-workspace extension that we can save anywhere. You may need to restart VSC to let it save and load the workspace nicely, at least for the VSC version that I used.

cd ~
mkdir -p Sandbox/vsc-example/simple-node-web

When the workspace is first saved, it has only one root level folder, simple-node-api. If we want to add another folder, we can click File -> Add Folder to Workspace... to add the simple-node-web folder.

Image 10

In the simple-node-web project, we will create a Node application to expose an HTML page index.html.

JavaScript
let express = require('express'),
    http = require('http'),
    path = require('path'),
    errorhandler = require('errorhandler');
    
let app = express();
    
app.set('port', 4000);
    
app.use(function (req, res, next) {
    res.header('Cache-Control', 'private, no-cache, no-store, must-revalidate');
    res.header('Expires', '-1');
    res.header('Pragma', 'no-cache');
    next();
});
    
app.use(express.static(path.join(__dirname, 'client')));    
    
app.use(errorhandler());
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});

The index.html makes Ajax calls to the simple-node-api to get the server time and displays it on the web page.

HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
    
<style>
    .time {
        font-family:Verdana;
        font-weight:600;
        padding: 15px;
        height: 25px;
        background-color:honeydew;
    }
    
</style>
    
<script>
    
window.addEventListener('load', function() {
    
    let divTime = document.getElementById("divTime");
    
    let loadTime = function() {
        let xhttp = new XMLHttpRequest();
    
        xhttp.onreadystatechange = function() {
            if (this.readyState === 4) {
                divTime.innerHTML = (this.status === 200)?
                    JSON.parse(this.responseText).time : '';
            }
        };
    
        xhttp.open("GET", "http://localhost:3000/time", true);
        xhttp.send();
    };
    
    setInterval(loadTime, 1000);
    loadTime();
});
    
</script>
    
</head>
    
<body>
<div class="time" id="divTime"/>
</body>
</html>

In a workspace, we can use the command terminal to start both applications. We can use CTL+SFT+'`' to open the terminals:

Image 11

We can then issue the following commands for both simple-node-api and simple-node-web to start them.

npm install
node app.js

If we now go to http://localhost:4000/index.html in the browser, we can see the current time is displayed in the web page.

Image 12

Debug & Debug Configurations

Simple Debug

VSC natively supports Node applications, so debugging a node application can be very simple. Simply select the file and click Debug => Start Debugging to start the debugging.

Image 13

If we place a break point in the code and go to http://localhost:3000/time, we can see that the application stops at the break point.

Image 14

Debug Configurations

For some reason, if the VSC is unable to figure out how to debug the application, or if we want to debug multiple applications simultaneously in the workspace, we need to manually add the debug configurations.

Image 15

The simple way to add a debug configuration is to place a file called launch.json in the corresponding .vscode folder. The following is the launch configuration for the simple-node-api application.

JavaScript
{
    "version": "0.2.0",
    "configurations": [
    
        {
            "type": "node",
            "request": "launch",
            "name": "simple-node-api",
            "program": "${workspaceFolder}/app.js"
        }
    ]
}

The following is the launch configuration for the simple-node-web application.

JavaScript
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "simple-node-web",
            "program": "${workspaceFolder}/app.js"
        }
    ]
}

With the debug launch configurations ready, we can type CTL+Shift+D to open the debug panel and select the configuration to start debugging. We can start multiple configurations simultaneously.

Image 16

Where are the Settings Files

Now we have seen the examples to use VSC to help us do the following:

  • Work on a single project by directly working on the folder.
  • Work on a workspace and work on multiple root level folders.
  • Debug a simple application and create debug configurations to manage more complicated debugging situations.

For the basic use cases, these are probably all that we need from VSC. Now I want to summarize the files that we can configure the behaviors of the VSC.

User Level Settings

The user level settings are configured in the ~/.config/Code/User/settings.json file. It applies to all the VSC instances launched by the user.

JavaScript
{
    "workbench.colorTheme": "Visual Studio Light",
    "terminal.integrated.rendererType": "dom",
    "files.enableTrash": false
}

Workspace Level Settings

The workspace level settings are configured in the vsc-example.code-workspace file. It applies to all the root level folders in the workspace.

JavaScript
{
    "folders": [
        {
            "path": "simple-node-api"
        },
        {
            "path": "simple-node-web"
        }
    ],
    "settings": {}
}

Folder Level Settings

The folder level settings are configured in the settings.json file in the corresponding .vccode directory.

JavaScript
{
    "files.exclude": {
        "**/package-lock.json": true,
        "**/.git": true,
        "**/.DS_Store": true,
        "**/node_modules": true
    }   
}

The behaviors of the VSC are controlled by the combination of the settings in the three files. Furthermore, if you want to disable ctrl+w to close the whole VSC program, you can add the follow to the keybindings.json file. This file is accessible by File -> Preferences -> Keyboard Shortcuts.

JSON
// Place your key bindings in this file to override the defaults
[
  { "key": "ctrl+w", "when": "!editorIsOpen" }
]

Points of Interest

  • This is a note on Visual Studio Code.
  • This note only covers the basic use cases of VSC. If you want to work on other languages, such as Python, you may need to install additional extensions.
  • I hope you like my posts and I hope this note can help you in one way or the other.

History

  • 29th April, 2019: First revision

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)