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.exportsandrequire) 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.jsonfilenpm init -yNote: You can run
npm initinstead and follow the on-screen prompts to setup apackage.jsonfile. - Install babel and nodemon
npm install @babel/cli @babel/core @babel/node @babel/preset-env nodemon --save-devNote: nodemon is a tool used to start NodeJS applications. It restarts the application when file changes in the application source directory are detected.
- Create
.babelrcfile, 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 aboutenvpreset options here - Add
buildandstartcommands 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
srcdirectorymkdir 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.