Mac Visual Studio Code
by John Vincent
Posted on November 19, 2021
Including configuration of ESLint, AirBnb, React, Express, Webpack and Prettier
There are also notes regarding debugging Express, Mocha and Webpack and Fixing ESLint errors.
Visual Studio Code
The underlying software is constantly changing and so this document is being continuously updated.
Downloaded for Mac and installed.
Command Line
"/Applications/Visual Studio Code.app/Contents/MacOS/Electron" <your-workspace>
Preferences
For Mac, preferences file is
/Users/jv/Library/Application Support/Code/User/settings.json
which is currently
{
"editor.renderIndentGuides": false,
"window.zoomLevel": 0,
"editor.tabSize": 2,
"editor.insertSpaces": false,
"editor.detectIndentation": false,
"prettier.useTabs": true,
"prettier.trailingComma": "es5",
"prettier.tabWidth": 2,
"prettier.printWidth": 120,
"prettier.singleQuote": true
}
The workspace settings file is located in your project at
.vscode/settings.json
Basic Commands
-
show all command:
shift+command+p
-
go to file:
command p
-
find in files:
shift command f
-
start debugging:
f5
-
toggle terminal: ^`
-
reformat code:
Shift Option F
-
Help
- command p
- ?
- command p
-
List commands
- command p
- ?
- >
- command p
-
Find a symbol
- command p
- ?
- #
- command p
Extensions
To install an extension
- View
- Extensions
- Search for the plugin
- Install
Installed the following:
- Bookmarks
- ESLint Plugin
- Import Cost
- json
- Live Server
- npm intellisense
- Open in Browser
- Path intellisense - autocomplete filenames in your code.
- Prettier - Code formatter
- PrintCode
- Search
node_modules
- Quickly search for node modules in your project. - To Do Tasks
May wish to install:
- JavaScript ES6 Snippets
- jQuery code snippets
- Mocha Latte
- REST Client
To Print Code
View
Command Palette
PrintCode
File is converted to Html and is shown in a browser from which it can be printed.
Create snippets
- Code, Preferences, User Snippets
Use
- New snippets file for
- Provide a name, for example
my
which will create file my.code-snippets
in ~/.vscode
or
- New Global snippets file
which will create file ~/Library/Application Support/Code/User/snippets/my.code-snippets
ESLint
To find ESLint package, see npm search
I have chosen to use Airbnb ESLint. Ref for details
Initial
This can be a useful starting point. I suggest you perform these steps in a junk directory.
cd
cd tmp
mkdir junk
cd junk
Initialize a new project
npm init
Install eslint
npm i eslint --save-dev
Run eslint
/node_modules/eslint/bin/eslint.js --init
I chose:
- To check syntax, find problems, and enforce code style
- Airbnb rules
and then whatever best describes the use.
For example .eslintrc.json
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": [
"airbnb-base"
],
"parserOptions": {
"ecmaVersion": 12
},
"rules": {
}
}
package.json
{
"name": "....",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"eslint": "^7.15.0",
"eslint-config-airbnb-base": "^14.2.1",
"eslint-plugin-import": "^2.22.1"
}
}
Configure a project
I have chosen to configure ESLint on a per project basis.
Add to package.json
, notice the versions:
"devDependencies": {
"eslint": "^4.9.0",
"eslint-config-airbnb": "^16.1.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^6.0.2",
"eslint-plugin-react": "^7.4.0"
}
If using Prettier, also add:
"eslint-config-prettier": "^2.9.0",
get packages
npm install
Re-open the workspace.
Base ESLint Rules
There are a great multitude of available rules. See ESLint Rules
The following I have found to be useful for all projects.
Edit .eslintrc.json
"rules": {
"object-curly-spacing": ["error", "always", { "objectsInObjects": false }],
"comma-spacing": ["error", { "before": false, "after": true }],
"space-in-parens": ["error", "never"],
"array-bracket-spacing": ["error", "never"],
"semi": ["error", "always"],
"key-spacing": ["error"],
"comma-dangle": ["error", "never"],
"no-trailing-spaces": "error",
"no-console": 0,
"indent": [2, "tab", { "SwitchCase": 1 }],
"no-tabs": 0,
"max-len": [
"error",
{
"code": 120,
"tabWidth": 2,
"comments": 120
}
],
...
Base Node ESLint Configuration
Create .eslintrc.json
{
"extends": ["airbnb", "prettier"],
"env": {
"node": true,
"browser": false,
"es6": true
},
"globals": {},
"rules": {
"no-console": 0,
"max-len": [
"error",
{
"code": 120,
"tabWidth": 2,
"comments": 120
}
],
"indent": [2, "tab", { "SwitchCase": 1 }],
"no-tabs": 0
},
"plugins": []
}
Base React ESLint Configuration
Create .eslintrc.json
in client
{
"extends": ["airbnb", "prettier", "prettier/react"],
"env": {
"browser": true
},
"parser": "babel-eslint",
"globals": {},
"rules": {
"no-console": 0,
"max-len": [
"error",
{
"code": 120,
"tabWidth": 2,
"comments": 120,
"ignoreTrailingComments": true,
"ignoreUrls": true,
"ignorePattern": "^import\\s.+\\sfrom\\s.+;$"
}
],
"indent": [2, "tab", { "SwitchCase": 1 }],
"no-tabs": 0,
"react/jsx-indent": ["off", 2],
"react/jsx-indent-props": ["off", 2],
"quotes": ["error", "single"],
"jsx-quotes": [2, "prefer-single"],
"jsx-a11y/anchor-is-valid": [
"error",
{
"components": ["Link"],
"specialLink": ["to"]
}
],
"react/destructuring-assignment": ["off", "always"],
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn"
},
"plugins": ["react", "jsx-a11y", "import", "react-hooks"]
}
Base Express ESLint Configuration
Create .eslintrc.json
in server
{
"extends": "airbnb",
"env": {
"node": true,
"browser": false,
"es6": true
},
"globals": {},
"rules": {
"indent": [2, "tab"],
"no-tabs": 0,
"react/jsx-indent": ["off", 2],
"react/jsx-indent-props": ["off", 2]
},
"plugins": []
}
Notice the extends
clause.
Base Browser ESLint Configuration
Create .eslintrc.json
{
"extends": [
"airbnb",
"prettier"
],
"env": {
"node": false,
"browser": true,
"es6": false,
"jquery": true
},
"globals": {},
"rules": {
"no-console": 0,
"max-len": [
"error",
{
"code": 120,
"tabWidth": 2,
"comments": 120
}
],
"indent": [
2,
"tab",
{
"SwitchCase": 1
}
],
"no-tabs": 0
},
"plugins": []
}
Notice the jquery
clause
Configuring ESLint
ESLint User Guide is an excellent source. There are a vast number of options, too many to discuss here.
Useful ESLint commands
Add to package.json scripts
ESLint Versions
"eslint-versions": "npm info eslint-config-airbnb@latest peerDependencies",
will list the latest peer dependencies. Useful for checking which package versions to include.
ESLint / Prettier Configuration Check
"eslint-check": "eslint-config-prettier index.js",
checks your ESLint configuration looking for inconsistencies between your ESLint and prettier configurations. Useful if you are having difficulties with Prettier.
ESLint Your Code
"lint": "eslint 'src/**/*.{js,jsx}' --quiet",
performs ESLint on all code in src
and its subfolders. All messages are written to stdout. Useful for viewing all ESLint problems in one place.
Note that folders may be ignored using .eslintignore
For example
node_modules
Removing ESLint errors
Switching directly to Airbnb ESLint, for one project, created far too many errors.
Thus, for this project, I chose to configure two linters
- UI code
- Node code
.eslintrc.json
in project root
{
"env": {
"node": true,
"browser": false,
"es6": true
},
"globals": {
},
"rules": {
"eqeqeq": 1,
"strict":"off",
"no-console": "off",
"camelcase": "off",
"no-unused-expressions": "off",
"indent": "off",
"comma-dangle": "off",
"object-curly-spacing": "off",
"import/newline-after-import": "off",
"prefer-const":"off",
"no-var":"off",
"space-before-function-paren": "off",
"quotes":"off",
"prefer-template":"off",
"space-infix-ops":"off",
"quote-props":"off",
"arrow-parens": "off",
"consistent-return":"off",
"guard-for-in":"off",
"arrow-spacing":"off",
"object-property-newline":"off",
"no-underscore-dangle":"off",
"prefer-arrow-callback":"off",
"brace-style":"off",
"func-names":"off",
"class-methods-use-this":"off",
"no-path-concat":"off",
"no-param-reassign":"off",
"space-unary-ops":"off",
"max-len":"off",
"padded-blocks":"off",
"no-multiple-empty-lines":"off",
"vars-on-top":"off",
"no-unused-vars":"off"
},
"plugins": [
],
"extends": "airbnb"
}
root/public/js/.eslintrc.json
{
"env": {
"node": false,
"browser": true,
"jquery": true
},
"globals": {
},
"rules": {
"eqeqeq": 1,
"no-console": "off",
"camelcase": "off",
"no-unused-expressions": "off",
"indent": "off",
"comma-dangle": ["off"],
"prefer-arrow-callback": "off",
"strict": "off",
"no-var": "off",
"vars-on-top": "off",
"prefer-template": "off",
"quotes": "off",
"quote-props": "off",
"space-infix-ops": "off",
"space-before-function-paren": "off",
"object-curly-spacing": "off",
"no-shadow": "off",
"brace-style": "off",
"no-multiple-empty-lines": "off",
"max-len": "off",
"func-names": "off",
"spaced-comment": "off",
"wrap-life": "off",
"no-multi-str": "off",
"padded-blocks": "off",
"wrap-iife": "off",
"object-shorthand": "off"
},
"plugins": [
//you can put plugins here
],
"extends": "airbnb"
}
This removes all errors from the workspace.
Fixing ESLint errors
Now I have time to remove the rules one-by-one, cleaning the code in an orderly manner.
In Code Rules
/* eslint-env node, mocha */
/* global describe, it, before, beforeEach, after, afterEach */
/* global document */
/* global $ */
Inline Code Rules
// eslint-disable-next-line no-multi-str
// eslint-disable-next-line no-plusplus
// eslint-disable-next-line import/no-named-as-default
// eslint-disable-next-line react/prefer-stateless-function
// eslint-disable-next-line no-useless-constructor
// eslint-disable-next-line no-mixed-operators
// eslint-disable-next-line react/no-typos
// eslint-disable-next-line function-paren-newline
// eslint-disable-line no-param-reassign
// eslint-disable-line react/forbid-prop-types
// eslint-disable-line react/no-typos
Disable all occurrences within file
/* eslint-disable global-require */
/* eslint no-restricted-globals: ["off"] */
/* eslint-disable import/no-named-as-default */
/* eslint-disable no-underscore-dangle */
/* eslint-disable no-param-reassign */
/* eslint-disable class-methods-use-this */
/* eslint-disable import/prefer-default-export */
/* eslint-disable max-len */
/* eslint-disable no-console */
/* eslint-disable react/no-multi-comp */
/* eslint-disable no-case-declarations */
/* eslint-disable no-unused-vars */
/* eslint-disable import/no-extraneous-dependencies */
Maximum length, set to 150 characters
/* eslint max-len: [2, 150, 4] */ // maximum length of 150 characters
function doSomething(event) {
// eslint-disable-next-line no-console
console.log(event.currentTarget.getAttribute('data-something'));
}
Configuring Prettier Plugin
Thus can be a real pest seemingly frequently changing.
To change a Visual Studio Code preferences for all workspaces, edit preferences file.
For Mac, preferences file is
/Users/jv/Library/Application Support/Code/User/settings.json
If only wish to make the change for a workspace, change the workspace settings file which is located in your project at
.vscode/settings.json
The current setup
.vscode/settings.json
Add Format on Save
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.tabCompletion": "on",
"editor.snippetSuggestions": "top"
}
Older versions
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.tabCompletion": "on",
"editor.snippetSuggestions": "top"
}
and
{
"eslint.autoFixOnSave": true
}
-
Disable the Prettier plugin
-
.prettierrc
{
"singleQuote": true,
"semi": true,
"tabWidth": 2,
"trailingComma": "none",
"useTabs": true,
"printWidth": 120
}
Edit .eslintrc.json
"extends": ["airbnb", "prettier"],
Beware of max-len
. The following will break Prettier
"max-len": [2, 100, 4],
Use the following code instead:
"max-len": ["error", {
"code": 100,
"tabWidth": 2
}]
or, better yet
"max-len": ["error", {
"code": 100,
"tabWidth": 2,
"comments": 100,
"ignoreTrailingComments": true,
"ignoreUrls": true,
"ignorePattern": "^import\\s.+\\sfrom\\s.+;$"
}]
Restart Visual Studio Code to enable the changes.
Prettier Plugin to Ignore Code
To ignore a piece of code, precede the code with
JavaScript
// prettier-ignore
JSX
{/* prettier-ignore */}
SCSS, CSS
/* prettier-ignore */
Markdown
<!-- prettier-ignore -->
To exclude files from formatting, add entries to the .prettierignore
file in the project root.
Prettier, Quotes or Double Quotes
By default, Prettier uses double quotes.
To override and use single quotes, create file .prettierrc
in root folder and enter:
"prettier.singleQuote": true,
or false for double quotes.
Debugger
Set conditional breakpoint
- Right click the breakpoint
- Enter the condition
Debugging Node Application
For simple usage:
- Select
.js
file - F5 to start the debugger.
To add a configuration:
- Debug icon (left nav)
- Gear icon (top of debug view)
Which creates a default launch.json
Use Add Configuration if necessary to get to the following
{
"type": "node",
"request": "launch",
"name": "Run my Application",
"program": "${workspaceRoot}/directory/file.js",
"args": ["arg1", "arg2"],
"env": {
"ENV_1": "value1",
"ENV_2": "value2"
}
}
Debugging Express Application
- Debug icon (left nav)
- Gear icon (top of debug view)
Which creates a default launch.json
Use Add Configuration if necessary to get to the following
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Attach to Process",
"processId": "${command:PickProcess}",
"port": 5858
},
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}/server.js"
},
{
"type": "node",
"request": "launch",
"name": "Launch Create-Music-Data",
"program": "${workspaceRoot}/create-music-data/create-all.js",
"runtimeArgs": ["--max-old-space-size=8192"]
}
]
}
- Open file to debugged and set a
breakpoint
. - F5 to start debugging app
Mocha
Install extensions
To run tests:
- Command Palette (Shift+CMD+P)
- Mocha: Run all tests
Debugging Mocha
- Debug icon (left nav)
- Gear icon (top of debug view)
- Which edits
launch.json
Add the following configuration
{
// Name of configuration; appears in the launch configuration drop down menu.
"name": "Run mocha",
// Type of configuration. Possible values: "node", "mono".
"type": "node",
// Workspace relative or absolute path to the program.
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
// Automatically stop program after launch.
"stopOnEntry": false,
// Command line arguments passed to the program.
"args": ["test/**/*.js", "--no-timeouts"],
// Workspace relative or absolute path to the working directory of the program being debugged. Default is the current workspace.
"cwd": "${workspaceRoot}",
// Workspace relative or absolute path to the runtime executable to be used. Default is the runtime executable on the PATH.
"runtimeExecutable": null,
// Environment variables passed to the program.
"env": { "NODE_ENV": "testing"}
},
- Debug view (top nav)
- Set a
breakpoint
. - Select 'Run Mocha'
- Click on the green arrow icon to start debugging.
Debugging Webpack
- Debug icon (left nav)
- Gear icon (top of debug view)
Which creates a default launch.json
For this example:
${workspaceRoot}
is VSCode root directorywebpack/play-4
is the root directory of the project code.
Use Add Configuration if necessary to get to the following
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Run webpack",
"program": "${workspaceRoot}/webpack/play-4/node_modules/.bin/webpack",
"cwd": "${workspaceRoot}/webpack/play-4/",
"args": [
"--config",
"${workspaceRoot}/webpack/play-4/webpack.config.js",
"--context",
"${workspaceRoot}/webpack/play-4",
"--output-path",
"${workspaceRoot}/webpack/play-4/dist"
]
},
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${file}"
}
]
}
- Open
webpack.config.js
and set abreakpoint
. - F5 to start debugging app
Debugging Mocha / Webpack
- Debug icon (left nav)
- Gear icon (top of debug view)
Which creates a default launch.json
Use Add Configuration if necessary to get to the following
{
"type": "node",
"request": "launch",
"name": "Run mocha",
"program": "${workspaceRoot}/node_modules/mocha/bin/_mocha",
"stopOnEntry": true,
"args": ["test/**/*.js", "--recursive", "--compilers", "js:babel-register", "--no-timeouts", "--devtool", "source-map"],
"cwd": "${workspaceRoot}",
"runtimeExecutable": null,
"env": { "NODE_ENV": "testing"}
},
- Use debugger statements
- F5 to start debugging app
Debugging React
This is easiest to perform with Chrome Developer Tools.
- Sources
- Webpack
- .
- find the source file
- Open the file
- Set breakpoints etc
Debugging React with Enzyme and Jest
- Debug icon (left nav)
- Gear icon (top of debug view)
Which creates a default launch.json
Use Add Configuration if necessary to get to the following
{
"type": "node",
"request": "launch",
"name": "Debug Enzyme Jest",
"program": "${workspaceRoot}/node_modules/jest/bin/jest.js",
"args": ["-i"],
"cwd": "${workspaceRoot}",
"outFiles": ["${workspaceRoot}/dist/**/*"],
"env": {
"NODE_ENV": "development"
},
"envFile": "${workspaceRoot}/.env"
}
- Use debugger statements
- F5 to start debugging app
Note
args -i
causes jest to run tests asynchronously
To obtain useful debug messages, use debug()
or html()
const ahref = countries.find('.country').at(1).find('a');
console.log('ahref ', ahref.debug());
Debugging Next.js
Add to .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "ORIG",
"skipFiles": ["<node_internals>/**"],
"port": 9229
}
]
}
To run the debugger
- Set a break point
- Select Debug mode
- Select
node.js (preview)
- Select
Run Script: dev nextjs-website
- Start the debugger
- Run the app
http://localhost:3200/
Debugger will stop at the break point.
Using Chrome Inspector
Add to package.json
"scripts": {
"inspect": "node --inspect src/main.js",
},
Set a breakpoint and run
npm run inspect
From Chrome browser
chrome://inspect
See
- Remote Target
- Click on your node app
JavaScript CPU Profiler
- Profiler
- Start & Stop
Displays Functions by Total Time.
Memory
- Heap Snapshot
- Take snapshot
Take multiple snapshots to determine where additional resources are being accumulated.
- Allocation instrumentation on timeline
- Stop
Useful
- Summary, also with a timeline
- Class filter, find my code
- Statistics