While working on Node Guidebook, a project I started to share my thoughts on building NodeJS applications, I needed to answers a couple of questions.
- Which do I use?
commonjs
(akamodule.exports
andrequire
) or the new ES6 modules? Note: As at NodeJS v11, ES6 modules are not supported in NodeJS. - How do I ensure a consistent code format and style?
Commonjs or ES6 Modules?
I decided to go with ES6 modules for Guidebook as it is the future of module management in Javascript.
I also decided to not use --experimental-modules
NodeJS flag - I personally don’t like the .mjs
extensions required to use it.
As a result, I chose to write ES6 modules code and compile down to ES5 commonjs
code using babel.
This seems rather counterintuitive. Why not use commonjs
modules directly and skip the compile step? Well, I reasoned that sometime in the near future, ES6 modules will be fully supported in NodeJS. When that day arrives, I can safely remove babel
and not have to touch any of my code.
A Gist About Babel
Babel is a piece of software used to transform ES6+ code into a backwards compatible version. Code transformation in babel is achieved through the use of small Javascript programs called plugins. For example, the @babel/plugin-transform-arrow-functions transforms ES6+ arrow functions to ES5 functions. To transform code, you simply specify the list of plugins to apply to it. To simplify the process of using multiple plugins, babel provides presets. A preset is a pre-determined collection of plugins. For example, the env preset includes all the plugins required to transform modern Javascript (ES6+) into a backwards compatible version.
Setting Up Babel
- Create a new directory for the ES6 modules app
mkdir es6-modules-app cd es6-modules-app
- Create a
package.json
filenpm init -y
Note: You can run
npm init
instead and follow the on-screen prompts to setup apackage.json
file. - Install babel and nodemon
npm install @babel/cli @babel/core @babel/node @babel/preset-env nodemon --save-dev
Note: nodemon is a tool used to start NodeJS applications. It restarts the application when file changes in the application source directory are detected.
- Create
.babelrc
file, the babel configuration file, with the following content{ "presets": [ "@babel/env", { "targets": { "node": "8" }, "modules": "commonjs" } ] }
"modules": "commonjs"
tells babel to transform ES6 modules to commonjs.
{ "targets": { "node": "8" } }
tells babel to compile against node 8. To compile against the current version of node, specify{ "targets": { "node": true } }
. Learn more aboutenv
preset options here - Add
build
andstart
commands to scripts section ofpackage.json
.
Your package.json file should look something like this. Note, however, that package version numbers may differ.
{
"name": "es6-modules-app",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "babel src -d dist",
"start": "node dist/index.js",
"start:dev": "nodemon src/index.js --exec babel-node"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
...
}
}
The build
command will compile code from the source directory, src
and output it to a destination directory dist
. Note: you are free to decide the directory names.
- Create a
src
directorymkdir src
- Create the following files with their contents
math.js
export const sum = a => b => a + b
export const prod = a => b => a * b
export const divide = a => b => {
if (b > 0) return a / b;
throw new Error('Cannot divide by 0');
}
index.js
import { sum, prod, divide } from './math.js'
console.log('sum of %d and %d = %d', 8, 10, sum(8)(10));
console.log('product of %d and %d = %d', 6, 5, prod(6)(5));
console.log('%d divided by %d = %d', 22, 5, divide(22)(5));
To start the application, run npm run start:dev
. While the application is running, editing either math.js
or index.js
reloads it. That is, you don’t have to stop and restart it.
To deploy your changes to production, run npm run build
. This creates a dist
directory which can be deployed to the production server.
Hope you enjoyed this article. See you in the follow up article. In the meantime, feel free to leave comments and suggestions.