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
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.
The default color theme comes with a black background.
Because I do not like the black background, I changed it to the white background.
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.
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
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.
For this example, we just need to add the "package.json" file and the "app.js" file.
{
"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.
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.
{
"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.
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.
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.
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.
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.
In the simple-node-web
project, we will create a Node application to expose an HTML page index.html.
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.
<!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:
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.
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.
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.
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.
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.
{
"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.
{
"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.
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.
{
"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.
{
"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.
{
"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.
[
{ "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