0% found this document useful (0 votes)
28 views

Node - Js Coding Standards

Node.js Coding Standards Carbon Framework

Uploaded by

saket.parasher
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
28 views

Node - Js Coding Standards

Node.js Coding Standards Carbon Framework

Uploaded by

saket.parasher
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Document Name : Node.js Coding Standards Version 1.

Document Type : Standards

Document Reference : EG-IS-QMS-STD-022

Document Summary
This document describes the Coding Standards and Guidelines that should be used in Airline control
systems.

Document Release Note


This document is released for use in IT
This document is subject to IT EITQAN Management Procedures
Comments, Suggestions or queries should be submitted to Process and Governance,
using the EITQAN feedback form.

Document Revision History


Version Status Update Comment By Date

1.0 Final Final Version


0.2 Reviewed Updated Version
0.1 Draft Initial Version Chandan & Nitish 12 Sep 2018

Definitions & List of Abbreviations


Abbreviation Description

Node.js Coding Standards Emirates Group Internal & Vendors Page 1 of 19


Table of Contents

1. Introduction .............................................................................................................................................................................. 3
1.1 Background ........................................................................................................................................................................ 3
1.2 Intended Audience .............................................................................................................................................................. 3
1.3 Scope of the document ....................................................................................................................................................... 3
1.4 Terminology ....................................................................................................................................................................... 3
1.5 Cautions .............................................................................................................................................................................. 4
2. Node.js projects ........................................................................................................................................................................ 4
2.1 Npm init .......................................................................................................................................................................... 4
2.2 Setup .npmrc............................................................................................................................................................................ 4
2.3 Add scripts to your package.json............................................................................................................................................. 5
2.4 Use environment variables ...................................................................................................................................................... 6
2.5 Use a style guide...................................................................................................................................................................... 6
2.6 Embrace async ......................................................................................................................................................................... 7
2.7 Handle errors ........................................................................................................................................................................... 7
2.8 Ensure your app automatically restarts .................................................................................................................................... 8
2.9 Cluster your app to improve performance and reliability ........................................................................................................ 8
2.10 Require all your dependencies up front ................................................................................................................................. 9
2.11 Use a logging library to increase errors visibility .................................................................................................................. 9
2.12 Use Helmet if you’re writing a web app .............................................................................................................................. 10
2.13 Monitor your applications ................................................................................................................................................... 10
2.14 Test your code ..................................................................................................................................................................... 11
3. Node.js Coding Standards as per NPM recommendation (for projects other than EK.com) .................................................. 12
3.1 Description ..................................................................................................................................................................... 12
3.2 Line Length .................................................................................................................................................................... 12
3.3 Indentation ..................................................................................................................................................................... 12
3.4 Curly braces ................................................................................................................................................................... 12
3.5 Semicolons ..................................................................................................................................................................... 13
3.6 Comma First .................................................................................................................................................................. 13
3.7 Quotes ............................................................................................................................................................................ 14
3.8 Whitespace ..................................................................................................................................................................... 14
3.9 Functions........................................................................................................................................................................ 14
3.10 Callbacks, Sync/async Style .......................................................................................................................................... 14
3.11 Errors ............................................................................................................................................................................. 15
3.12 Logging .......................................................................................................................................................................... 15
3.13 Case, naming, etc. .......................................................................................................................................................... 15
3.14 null, undefined, false, 0 .................................................................................................................................................. 15
4. Node.js Structure .................................................................................................................................................................... 16
4.1 An Example ................................................................................................................................................................... 16
5. The conclusion ........................................................................................................................................................................ 17
Node.js Coding Standards Emirates Group Internal & Vendors Page 2 of 19
1. Introduction
It sure is easy to get started on those Node.js projects, but once you get beyond the basic Hello
World app, knowing how to best structure your code and how to deal with errors can sometimes
become a nightmare (as with most languages and frameworks). And unfortunately, that nightmare
makes all the difference between a rock solid production application and a launch disaster.

With that said, let's take a look at a few best Node.js practices that will keep you safe from the most
common Node.js traps.

1.1 Background
This document provides standards to which Node.js should be written and maintained. Close
adherence to the rules will help the consultants other than the author to understand a piece of
code.
The aim is to ensure that code is

Developed in a common manner


Produced quickly
Accurate
Reliable
Reusable
Easy to understand
Easy to modify, maintain and test

There is also a need to achieve these aims without unduly restricting the software
consultants' creativity or unnecessarily increasing the quantity of work beyond that merited
by the project/product.

1.2 Intended Audience


Below are the intended audiences
Node.js Architects
Node.js developers
Node.js reviewers

1.3 Scope of the document



This document to be referred when we going to start a new project or enhancement for node.js
project .It illustrate the best practice to be followed while starting a new projects.

1.4 Terminology

Where recommendations are made that represents the position of this document the verb
should is used and where alternate approaches are provided and no firm recommendations
are made, the verb may is used. Where firm recommendations are made the word must is
used

Node.js Coding Standards Emirates Group Internal & Vendors Page 3 of 19


The examples given indicate that those are for illustration purpose only and do not form a
part of the code examples

1.5 Cautions

The recommended standards and guidelines do not prohibit special considerations for
other systems, application specific requirements and hardware constraints
Examples are incorporated in this document to enhance clarity and promote understanding.
Examples should not be considered as the recommended implementations

2. Node.js projects

2.1 Npm init

Most people are familiar with NPM as a way to install dependencies, but it is so much more than
this. First, I highly recommend creating a new project using npm init, like so:
$ mkdir my-new-project
$ cd my-new-project
$ npm init

This will create a new package.json for you which allows you to add a bunch of metadata to
help others working on the project have the same setup as you.

For example, I usually open the package.json and add a specific version of Node.js
"engines": {
"node": "8.11.3"
}

2.2 Setup .npmrc


If you’ve used npm before, you may have come across the - -save flag which updates
the package.json with the dependency. When other developers clone the project, they can be
sure to have the right dependencies because of this. Unfortunately, remembering to add the flag can
be a problem.
In addition, NPM adds a leading caret ^ to all versions. Consequently, when someone runs npm
install, they may get different versions of the modules than what you have. While
updating modules is always a good practice, having a team of developers all running against
slightly different versions of dependencies can lead to differences in behaviour or availability of
APIs.
Therefore, it’s a good idea to have everyone on the same version. To make this easier for eve ryone,
the .npmrc file has some useful properties that can make sure npm install always updates
the package.json and enforces the version of installed dependency to be an exact match.

Node.js Coding Standards Emirates Group Internal & Vendors Page 4 of 19


Simply run the following lines in your terminal:
$ npm config set save=true
$ npm config set save-exact=true
Now when you run npm install, you can be sure the dependency is saved and will be locked
down to the version you installed.

2.3 Add scripts to your package.json


If there’s one thing all applications need, it’s a launch script. Knowing which file to call first and
with what arguments can be an epic adventure of discovery on some projects. Good thing NPM has
a standard way to start all node applications.

Simply add a scripts property and object to your package.json with a start key. Its value
should be the command to launch your app.
For example:
"scripts": {
"start": "node myapp.js"
}

As soon as someone runs npm start, NPM will run node myapp.js with all the
dependencies from node_modules/.bin on your $PATH. This means you can avoid having to
do global installs of NPM modules.

There’s a couple of other script hooks worth knowing:


"scripts": {
"postinstall": "bower install && grunt build",
"start": "node myapp.js",
"test": "node ./node_modules/jasmine/bin/jasmine.js"
}

The postinstall script is run after npm install is run. There’s also preinstall if you
need to run something before all the NPM dependencies are installed.

The test script is run when someone runs npm test. This is a nice simple way for someone to
be able to run your tests without figuring out if you’ve chosen to use Jasmine, Mocha, Selenium,
etc.

You can add your own custom scripts here, too. They can then be run using npm run-script
{name} - a simple way for you to give your team a central set of launch scripts.

Node.js Coding Standards Emirates Group Internal & Vendors Page 5 of 19


2.4 Use environment variables
Configuration management is always a big topic in any language. How do you decouple your code
from the databases, services, etc. that it has to use during development, QA, and production?

The recommended way in Node.js is to use environment variables and to look up the values
from process.env in your code.

For example, to figure out which environment you’re running on, check
the NODE_ENV environment variables:
console.log("Running in :" + process.env.NODE_ENV);

This is now a standard variable name used across most cloud-hosting vendors.

2.5 Use a style guide


I know we’ve all had those moments where we open a new file from another project for the first
time or the file came from a different developer, we then spend the next hour reformatting the
braces to be on different lines, changing the spaces to tabs, and vice versa.

The problem here is a mixture of opinionated developers and no team/company standard style
guide.

It’s far easier to understand code on a codebase if it’s all written in a consistent style. It also
reduces the cognitive overhead of whether you should be writing with tabs or spaces. If the style is
dictated (and enforced using JSHint, ESlint or JSCS) then all of sudden, the codebase becomes a lot
more manageable.

You don’t have to come out with your own rules either, sometimes it’s better to pick an existing set
of guidelines and follow them.

We follow Airbnb JS Style Guide and developers should ensure they adhere to the standards using
ESLint

Node.js Coding Standards Emirates Group Internal & Vendors Page 6 of 19


2.6 Embrace async
I’m sure you’ve heard all the hype about promises, maybe even heard a little about async /
await and generators in ES2016. The key idea behind all these techniques is making your
code async.

The problem with synchronous functions in JavaScript is that they block any other code from
running until they complete. However, synchronous code makes the flow of your application logic
easy to understand. On the other hand, async structures like promises actually bring back a lot of
that reasoning while keeping your code free from blockages.

So first, I highly recommend running your app (during development only) with the --trace-
sync-io flag. This will print a warning and stack trace whenever your application uses a
synchronous API.

There are plenty of great articles about how to use promises, generators and async / await.

I don't need to duplicate other great work that's already available, so here’s a few links to get you
started:
 Promises - http://www.html5rocks.com/en/tutorials/es6/promises/
 Async / Await - https://javascript.info/async-await
 Generators
- https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Iterators_and_Gener
ators

2.7 Handle errors


Having an error bring down your entire app in production is never a great experience. Good
exception management is important for any app, and the best way to deal with errors is to use the
async structures above. For example, promises provide a .catch() handler that will propagate
all errors to be dealt with, cleanly.

Let’s say you have a chain of promises, and any one of which could suddenly fail, you can easily
handle the error like so:
doSomething()
.then(doNextStage)
.then(recordTheWorkSoFar)
.then(updateAnyInterestedParties)
.then(tidyUp)
.catch(errorHandler);

In the example above, it doesn’t matter which of the earlier functions could have failed, any error
will end up in the errorHandler.
Node.js Coding Standards Emirates Group Internal & Vendors Page 7 of 19
2.8 Ensure your app automatically restarts
Okay, so you followed the best practice to handle errors. Unfortunately, some error from a
dependency still, somehow, brought down your app

This is where it’s important to ensure you use a process manager to make sure the app recovers
gracefully from a runtime error. The other scenario where you need it to restart is if the entire
server you’re running on went down. In that situation, you want minimal downtime and for you
application to restart as soon as the server is alive again!
I’d recommend using KeyMetric’s PM2 http://pm2.keymetrics.io/ to manage your process.
Though other options include (Nodemon)[http://nodemon.io/] and (Forever)
[https://github.com/foreverjs/forever].

First, install it as a global module:


$ npm install pm2 -g

Then to launch your process, you should run:


$ pm2 start myApp.js
To handle restarting after the server crashes, you can follow the PM2 guide for you platform:
 http://pm2.keymetrics.io/docs/usage/startup/

2.9 Cluster your app to improve performance and reliability


By default Node.js is run in a single process. Ideally, you want one process for each CPU core so
that you can distribute the work load across all the cores. This improves scalability of web apps
processing HTTP requests and performance in general. In addition to this, if one worker crashes,
the others are still available to handle requests.
One of the other benefits of using a process manager like PM2 is that it supports clustering out of
the box:
 http://pm2.keymetrics.io/docs/usage/cluster-mode/

To start up multiple instances of your app for each core on a machine, you’d simply run:
$ pm2 start myApp.js -i max

One thing to bear in mind is that each process is standalone — they don’t share memory, or
resources. Each process will open its own connections to databases,

For example. Always keep that in mind as you code. A useful tool people use to share session state,
for example, is Redis, this provides an in-memory datastore that can be quickly accessed by all the
processes to store session related data.

Node.js Coding Standards Emirates Group Internal & Vendors Page 8 of 19


2.10 Require all your dependencies up front
I’ve seen many developers write code like this:
app.get("/my-service", function(request, response) {
var datastore = require("myDataStoreDep")(someConfig);

datastore.get(req.query.someKey)
// etc, ...
});

The problem with the code above is that when someone makes a request to /my-service, the
code will now load all files required by myDataStoreDep - any of which could throw an
exception.

Additionally, when the configuration is passed on, there could also be an error at that point which
can bring down the entire process. In addition, we don’t know how long that synchronous setup of
a resource will take. At this point in the code, we essentially block all other requests from being
handled!

So you should always load all your dependencies upfront and configure them upfront. That way,
you'll know from the start up if there is a problem, not three to four hours after your app has gone
live in production!

2.11 Use a logging library to increase errors visibility


console.log is great but it has limits in a production application. Trying to sift through
thousands of lines of logs to find the cause of the bug… which I guarantee you will have to do at
some point, is painful!

A mature logging library can help with this. First, they allow you to set levels for each log
message - whether it’s a debug, info, warning, or error.

In addition, they typically allow you to log to different files or even remote data store.

For example,
You can use Loggy [https://www.loggly.com/] or
Kibana [https://www.elastic.co/products/kibana].

It allows to quickly search all log messages using patterns. In addition, it can alert if a threshold is
reached - for example, if a web application starts returning 500 SERVER ERROR messages to the
users for a period longer than 30 seconds, it can send a message and now you can figure out what’s
going on.

Node.js Coding Standards Emirates Group Internal & Vendors Page 9 of 19


2.12 Use Helmet if you’re writing a web app
If you’re writing a web application, there are a lot of common best practices that you should follow
to secure your application:
 XSS Protection
 Prevent Clicking jacking using X-Frame-Options
 Enforcing all connections to be HTTPS
 Setting a Context-Security-Policy header
 Disabling the X-Powered-By header so attackers can’t narrow down their attacks
to specific software

Instead of remembering to configure all these headers, Helmet will set them all to sensible defaults
for you, and allow you to tweak the ones that you need.

It’s incredibly simple to set up on an Express.js application:


$ npm install helmet

And then in your code when setting up Express add:


var helmet = require('helmet');
app.use(helmet());

2.13 Monitor your applications


Getting notified when something goes wrong with your application is critical on production
applications. You don’t want to check your Twitter feed and see thousands of angry users telling
you your servers are down or your app is broken and has been for the last few hours. So having
something monitoring and alerting you to critical issues or abnormal behaviour is important.

We already discussed in Chapter (2.8), PM2 for process management. In addition it’s
developers KeyMetrics.io run a process monitoring SaaS with integration with PM2 baked in. It’s
very simple to enable and they have a free plan which is a great starting point for a lot of
developers. Once you’ve signed up for KeyMetrics, you can simply run:
$ pm2 interact [public_key] [private_key] [machine_name]

This will start sending memory & CPU usage data, plus exception reporting to key metrics servers
to view from their dashboard. You can also view latency of your http requests, or set up events
when problems occur (for example timeouts to downstream dependencies).

Node.js Coding Standards Emirates Group Internal & Vendors Page 10 of 19


In addition, Loggly / Kibana (that we mentioned earlier) also provides monitoring based off logs.
Both tools in combination can provide you with a way to quickly react to problems before they get
out of hand.

2.14 Test your code


Seriously though, testing will save your ass on many occasions. Like creating any new habit, it’s
painful to start and keep up the momentum. It gets in the way of your speed of development.
However, once the first few production issues occur on a project with no tests, you’ll wish you had
in the first place.

No matter what stage you are on a project, it’s never too late to introduce testing. My advice is start
small, start simple. I’d also highly recommend writing a test for every bug that gets reported. That
way you know:
 How to reproduce the bug (make sure your test fails first!)
 That the bug is fixed (make sure you test passes after you fix the issue)
 That the bug will never occur again (make sure you run your tests on every new
deployment)

We use Jest as the Unit Testing framework. Developers should make sure unit test cases are written
for all the new components that are created or update test cases whenever an existing component is
enhanced/modified. Test cases coverage should be more than 80%.

Node.js Coding Standards Emirates Group Internal & Vendors Page 11 of 19


3. Node.js Coding Standards as per NPM recommendation (for
projects other than EK.com)

3.1 Description

Node.js coding style is a bit unconventional. It is not different for difference's sake, but rather a
carefully crafted style that is designed to reduce visual clutter and make bugs more apparent.

Best is to follow npm's style coding. So, in future it will be easy to contribute to npm.

3.2 Line Length

Keep lines shorter than 80 characters. It's better for lines to be too short than to be too long. Break up
long lists, objects, and other statements onto multiple lines.

3.3 Indentation

Two-spaces. Tabs are better, but they look like hell in web browsers (and on GitHub), and node uses
2 spaces, so that's that.

Configure your editor appropriately.

3.4 Curly braces

Curly braces belong on the same line as the thing that necessitates them.
Bad:
function ()
{

Good:
function () {

If a block needs to wrap to the next line, use a curly brace. Don't use it if it doesn't.
Bad:
if (foo) { bar() }
while (foo)
bar()

Node.js Coding Standards Emirates Group Internal & Vendors Page 12 of 19


Good:
if (foo) bar()
while (foo) {
bar()
}

3.5 Semicolons
Don't use them except in four situations:
A. for (;;) loops. They're actually required.
B. null loops like: while (something) ; (But you'd better have a good reason for doing that.)
C. case 'foo': doSomething(); break
D. In front of a leading ( or [ at the start of the line. This prevents the expression from being
interpreted as a function call or property access, respectively.

Some examples of good semicolon usage:


;(x || y).doSomething()
;[a, b, c].forEach(doSomething)
for (var i = 0; i < 10; i ++) {
switch (state) {
case 'begin': start(); continue
case 'end': finish(); break
default: throw new Error('unknown state')
}
end()
}

Note that starting lines with - and + also should be prefixed with a semicolon, but this is much less
common.

3.6 Comma First

If there is a list of things separated by commas, and it wraps across multiple lines, put the comma at
the start of the next line, directly below the token that starts the list. Put the final token in the list on a
line by itself.

Node.js Coding Standards Emirates Group Internal & Vendors Page 13 of 19


For example:
var magicWords = [ 'abracadabra'
, 'gesundheit'
, 'ventrilo'
]
, spells = { 'fireball' : function () { setOnFire() }
, 'water' : function () { putOut() }
}
, a = 1
, b = 'abc'
, etc
, somethingElse

3.7 Quotes
Use single quotes for strings except to avoid escaping.

Bad:
var notOk = "Just double quotes"

Good:
var ok = 'String contains "double" quotes'
var alsoOk = "String contains 'single' quotes or apostrophe"

3.8 Whitespace

Put a single space in front of ( for anything other than a function call. Also use a single space
wherever it makes things more readable.

Don't leave trailing whitespace at the end of lines. Don't indent empty lines. Don't use more spaces
than are helpful.

3.9 Functions

Use named functions. They make stack traces a lot easier to read.

3.10 Callbacks, Sync/async Style

Use the asynchronous/non-blocking versions of things as much as possible. It might make more sense
for node.js to use the synchronous fs APIs, but this way, the fs and http and child process stuff all
uses the same callback-passing methodology.

Node.js Coding Standards Emirates Group Internal & Vendors Page 14 of 19


The callback should always be the last argument in the list. Its first argument is the Error or null.

Be very careful never to ever ever throw anything. It's worse than useless. Just send the error message
back as the first argument to the callback.

3.11 Errors
Always create a new Error object with your message. Don't just return a string message to the
callback. Stack traces are handy.

3.12 Logging

Please clean up logs when they are no longer helpful. In particular, logging the same object over and
over again is not helpful. Logs should report what's happening so that it's easier to track down where
a fault occurs.
Use appropriate log levels.

3.13 Case, naming, etc.

 Use lowerCamelCase for multiword identifiers when they refer to objects, functions, methods,
properties, or anything not specified in this section.
 Use UpperCamelCase for class names (things that you'd pass to "new").
 Use all-lower-hyphen-css-case for multiword filenames and config keys.
 Use named functions. They make stack traces easier to follow.
 Use CAPS_SNAKE_CASE for constants, things that should never change and are rarely used.
 Use a single uppercase letter for function names where the function would normally be anonymous,
but needs to call itself recursively. It makes it clear that it's a "throwaway" function.

3.14 null, undefined, false, 0

 Boolean variables and functions should always be either true or false. Don't set it to 0 unless it's
supposed to be a number.
 When something is intentionally missing or removed, set it to null.
 Don't set things to undefined. Reserve that value to mean "not yet set to anything."

Node.js Coding Standards Emirates Group Internal & Vendors Page 15 of 19


4. Node.js Structure

Node.js is not a framework like Rails or .Net. Only the experience working in different projects will let
anyone define the best structure for every situation.

4.1 An Example
For Example Below structure can be used:

.
├── config # App configuration files
│ ├── sequalize.json # Sequalize config
│ ├── serviceOne.json # ServiceOne config
│ └── ... # Other configurations
├── routes
│ ├── controllers # Request managers
│ ├── middlewares # Request middlewares
│ └── routes.js # Define routes and middlewares here
├── services # External services implementation
│ ├── serviceOne
│ └── serviceTwo
│ └── ... # Other services
├── db # Data access stuff (Sequalize mostly)
│ ├── models # Models
│ ├── migrations # Migrations
│ ├── seeds # Seeds
│ └── index.js # Sequalize instantiation
├── core # Business logic implementation
│ ├── accounts.js
│ ├── sales.js
│ ├── comments.js
│ └── ... # Other business logic implementations
├── utils # Util libs (formats, validation, etc)
├── tests # Testing
├── scripts # Standalone scripts for dev uses
├── pm2.js # pm2 init
├── shipitfile.js # deployment automation file
├── package.json
├── README.md
└── app.js # App starting point

Node.js Coding Standards Emirates Group Internal & Vendors Page 16 of 19


5. The conclusion

This folder structure follows the idea of making things simple. Don’t over engineer things, keep it
simple! Maybe the project is simpler than what we are using as an example here, so go on and make it
lighter.

But what if the project gets bigger? You can modularize the structure grouping your core files into
subfolders that represent different components of your application (like Users, Administration,
Statistics, etc.).

Other way to modularize it is to create different projects and deploy each one as a different process or
service, so you can have multiple independent projects (this is called Microservices).

And remember, when creating project structures, just pick the easiest thing that you could make and do
it! Don’t over engineer it and just do it!

6. Additional references
Additional reference can be found on the below link which has the Node.js documentations

https://nodejs.org/en/docs/

https://nodejs.org/en/docs/guides/

https://www.codementor.io

Node.js Coding Standards Emirates Group Internal & Vendors Page 17 of 19

You might also like