DEV Community

Norbert Braun
Norbert Braun

Posted on • Originally published at Medium on

My Node.js Setup (Mocha & Chai, Babel7, ES6)

Me and Gojira writing unit tests

Every time I want to code something I try to build a decent development environment for my projects. I usually install Babel to compile ES6/ES7 back to ES5, Mocha & Chai for unit testing purposes, and Nodemon to automatically restart the app.

So I decided to share my experience of setting up node environments from scratch. I hope you may find this information useful.

First, let’s generate an empty package.json for our project.

npm init -y
Enter fullscreen mode Exit fullscreen mode

Now, we can add some development dependencies.

npm install --save-dev @babel/cli @babel/core @babel/node @babel/register @babel/preset-env chai mocha nodemon
Enter fullscreen mode Exit fullscreen mode

After the installation our package.json should look like this:

package.json

Babel 7 packages are now “scoped” so the old babel-cli became @babel /cli.

ES6 & Node

Create an index.js file with a simple function that returns a string so we can test if everything is correct. I always put my index file to the root of a src folder. If you place it somewhere else remember to adjust the path in your package.json scripts accordingly.

./src/index.js


const sayHello = _ => "Hello guys!"

console.log(sayHello())
Enter fullscreen mode Exit fullscreen mode

To see the result, copy and paste the following script to your package.json.

"start": "nodemon ./src/index.js",
Enter fullscreen mode Exit fullscreen mode

After typing npm start in the console/terminal, you will see something like this:

nodemon running

Nodemon monitors every change in your code and automatically starts the application again if you change something. Place an ES6 export statement to the end of the index.js file and run the app again.

export default sayHello
Enter fullscreen mode Exit fullscreen mode

The result is:

Node can’t recognize ES6 export/import keywords. To fix that, we need babel to compile our export default sayHello to something like exports.default = sayHello.

To do that, we need a file in our project root called .babelrc. Copy and paste the following code into it.

{

"presets": ["@babel/preset-env"]

}
Enter fullscreen mode Exit fullscreen mode

Next, we need to adjust our start script as well.

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

Testing

Okay, let’s write a quick test to see if it works. Remember we have already installed chai and mocha so we can use them without any further configuration.

./test/index.spec.js


import { expect } from "chai"
import sayHello from "../src/index"

describe("index test", () => {
    describe("sayHello function", () => {
        it("should say Hello guys!", () => {

            const str = sayHello();
            expect(str).to.equal("Hello guys!")
        })
    })
})
Enter fullscreen mode Exit fullscreen mode

Also, we need a test script in our package.json:

"test": "./node_modules/.bin/mocha --compilers js:@babel/register"
Enter fullscreen mode Exit fullscreen mode

Three important facts about the test script:

  • If you install mocha globally with npm install -g you can use "mocha --compilers js:@babel /register" instead.
  • Since our test file is located in the test folder, mocha finds our index.spec.js automatically.
  • The --compilers js:@babel /register tells mocha that we use ES6 so it should take care of it. That’s why we installed @babel /register.

Type npm test in your console/terminal and you will see the test passing.

Compiling to the Dist Folder

If you are curious how your compiled ES5 compatible code looks like you can add the following scripts to your package.json.

"build": "babel src --out-dir ./dist --source-maps",

"serve": "node ./dist/index.js",
Enter fullscreen mode Exit fullscreen mode

The npm run build command will create a compiled index.js file in the dist folder and the npm run serve will run that instead of the original in the src folder. We also use --source-maps so that when we debug our ./dist/index.js we can see the actual ES6 code that we wrote.

Debugging

I am a JS developer so I rather debug my code using a browser than an IDE.

Fortunately, node allows us to debug our applications in a browser. Here’s another script for your package.json.

"debug": "node --inspect-brk ./dist/index.js"
Enter fullscreen mode Exit fullscreen mode

After npm run debug you can see the following message.

node debug

Take the highlighted string that was generated for you and append it to this url:chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:9229/.

Then, paste it to the browser and you are done.

Happy debugging!

The End

So, that’s it. Next time, I’ll dig deeper into interesting JS/Python/Rust programming concepts as well.

If you get stuck or know a better way to do this don’t hesitate to leave a comment.

Thanks for reading. Feel free to clone the repository from here.

Top comments (4)

Collapse
 
multiplaie profile image
Remy Jacquand • Edited

Hey norbert,

thank you for this post !

i have just one thing to correct:

in the test script

"test": "./node_modules/.bin/mocha --compilers js:@babel/register"
Enter fullscreen mode Exit fullscreen mode

--compilers is now deprecated

you can fix this with

"test": "./node_modules/.bin/mocha --require @babel/register"
Enter fullscreen mode Exit fullscreen mode

peace


source: github.com/mochajs/mocha/wiki/comp...

Collapse
 
popham profile image
Tim Popham

Thanks for the schematic. It helped me work around some difficulty that I was having with configuring Mocha to work with Flow.

I noticed some bad advice, however, under your test script. NPM adds the .node_modules/.bin directory to the path when you run any npm script, so the ./node_modules/.bin/mocha is unnecessary--mocha alone is sufficient. Further, relying on your global installs in your scripts is non-portable. You shouldn't impose on your users to reproduce your global environment on their machines.

Collapse
 
drozerah profile image
Drozerah

ARROW FUNCTIONS

If we take a look at the Mocha documentation page, we can read "Passing arrow functions (aka "lambdas") to Mocha is discouraged. Lambdas lexically bind this and cannot access the Mocha context."

=> mochajs.org/#arrow-functions

Collapse
 
oliverke profile image
Kelechi Oliver A.

Thanks for the article, after following your tutorial, I'll like to host my node app on Heroku, is it ok to have both the src folder and the dist folder been sent to Heroku in production mode?