Making the debuggers work

andrewallison

Andy Allison

Posted on October 25, 2019

Making the debuggers work

Ok so as a member of a team that use both Vscode and Webstorm and someone who likes to jump between them himself I really wanted a nice easy way to spin up a simple Javascript project that would let me use all the nice new features from ES6 (particularly the imports / modules and other syntactic sugar).

The best way to do this is weith Babel

Initialise npm and a package.json. Using -y will skip all the questions and adding details manually you can go back and modify later.

$ npm init -y
Enter fullscreen mode Exit fullscreen mode

Install the dependencies needed.

$ npm i dotenv @babel/cli @babel/core @babel/node @babel/preset-env nodemon
Enter fullscreen mode Exit fullscreen mode

Create a folder called /src with another folder called /modules in it. In the /src folder create a new file called index.js. Then in the modules folder create another file called maths.js. The final structure should look like something below.

Folder structure

// /src/index.js
import 'dotenv/config';

import { sumAll } from './modules/maths';

const result = sumAll(1, 1);

console.log(result);
Enter fullscreen mode Exit fullscreen mode
// /src/modules/maths.js
let sumAll = (a, b) => { return a + b; }
let subtractAll = (a, b) => { return a - b; }
let divideAll = (a, b) => { return a / b; }
let multiplyAll = (a, b) => { return a * b; }
let findModulus = (a, b) => { return a % b; }

export { sumAll, subtractAll, divideAll, multiplyAll, findModulus };
Enter fullscreen mode Exit fullscreen mode

The tricky part is this bit. If you try to run this project with out babel you will end up with the following error.

c:\dev\Learning\nodejs\babel-es6-debugging\src\index.js:1
import 'dotenv/config';
       ^^^^^^^^^^^^^^^

SyntaxError: Unexpected string
    at Module._compile (internal/modules/cjs/loader.js:721:23)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:787:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:829:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
Enter fullscreen mode Exit fullscreen mode

SOOOOOOO.. To get this rocking we do this bit o magic. Stick a file called .babelrc in the root folder of the project. Use the following snippet to kick up the presets and make it produce sourMaps

// .babelrc
{
    "presets": [
        "@babel/preset-env"
    ],
    "sourceMaps": true
}
Enter fullscreen mode Exit fullscreen mode

Then in the package.json file add the following to the "scripts" section.

"scripts": {
  "start": "nodemon --exec babel-node src/index.js"
},
Enter fullscreen mode Exit fullscreen mode

Running

$ npm run start
Enter fullscreen mode Exit fullscreen mode

Should produce this. Showing that we have managed to transpile and run the script

[nodemon] 1.19.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: js,mjs,json
[nodemon] starting `babel-node src/index.js`
2
[nodemon] clean exit - waiting for changes before restart
Enter fullscreen mode Exit fullscreen mode

BUT WHAT ABOUT DEBUGGING

Yes, don't worry I hadn't forgot, this was the bit that actually caused me some realy head scratching. I could add lots of links to the numerous StackOverflows, blogs, videos and issues I've plodded through in order to get this working but I think I'll just give you the solutions as once it works it works.

Start by adding @babel/register this is a little touch of hot sauce that means you can run the babel files in memory rather than having to do the whole. Build into dist folder thang.

$ npm i --save-dev @babel/register
Enter fullscreen mode Exit fullscreen mode

Then create a babel.config.js file in the root of the project. The file contents needs to look like.

module.exports = {
    presets: [
        [
            '@babel/preset-env',
            {
                // sourceMaps: true,
                targets: {
                    node: 'current',
                },
            },
        ],
    ],
};
Enter fullscreen mode Exit fullscreen mode

VSCode

SO next in vscode go to the configuration / debug section and make the launch.json file look like.

The most interesting parts are the args for the working folder. This needs to pint at the correct file for the debugging. IN this case and index.js. Then the runTimeArgs are needed to transpile the babely babel stuff in-memory rather than with a dist folder.

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "Launch",
            "args": [
                "${workspaceRoot}/src/index.js"
            ],
            "restart": true,
            "protocol": "inspector",
            "stopOnEntry": false,
            "runtimeArgs": [
                "--nolazy",
                "--require",
                "@babel/register"
            ],
            "sourceMaps": true
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

From here you should be able to hit F5 with a breakpoint in place and have it hit that.

Webstorm

In webstorm the easiest way to do this is to open the index.js and use a right click Debug File. This will give you a configuration in the config manager.

In there it will end up looking like
Config Settings

In the Node parameters field add

--nolazy --require @babel/register 
Enter fullscreen mode Exit fullscreen mode

Make sure the configuration is saved, close the dialog and hit the little red debug button with a breakpoint added.

Bonus

next few tips are just to finish the boiler plate off

I personally like using commitizen to make sure there is a structure to my commits this allows a number of other things to be done at a later stage. Start by adding the dependencies.

$ npm i --save-dev commitizen cz-conventional-changelog
Enter fullscreen mode Exit fullscreen mode

Next add the following section to the bottom of the package.json

  "config": {
    "commitizen": {
      "path": "./node_modules/cz-conventional-changelog"
    }
  }
Enter fullscreen mode Exit fullscreen mode

Then add the following to the "script"section of the package.json file:

    "cm": "git add -A && git cz",
Enter fullscreen mode Exit fullscreen mode

Next to stop us committing a load of rubbish that we don't need create a file in the root directory called .gitignore add the following into it.

node_modules/
.idea/
.vscode/
dist/

.env
Enter fullscreen mode Exit fullscreen mode

This will stop the directories being added to source control as we don't want them up there.

Finally you can run

$ npm run cm
Enter fullscreen mode Exit fullscreen mode

This will add all the files to git staging and trigger the commitizen template and ask you a number of questions about the commit.

? Select the type of change that you're committing: (Use arrow keys)
> feat:        A new feature
  fix:         A bug fix
  improvement: An improvement to a current feature
  docs:        Documentation only changes
  style:       Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
  refactor:    A code change that neither fixes a bug nor adds a feature
  perf:        A code change that improves performance

Enter fullscreen mode Exit fullscreen mode

This will allow you to enter details about the commit and push if you need to.

Round up

Ok so after alllllllll this you should be able to debug ES6 javascript in Vscode and Webstorm. If thrown together a repo on github with all the files in.
https://github.com/AndrewAllison/babel-es6-debugging andy feedback is much appreciated.

💖 💪 🙅 🚩
andrewallison
Andy Allison

Posted on October 25, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Making the debuggers work
debugging Making the debuggers work

October 25, 2019