Setting up Node JS, Express, MongoDB, Prettier, ESLint and Husky Application with Babel and authentication as an example
- Mohammad Abu Mattar
- Backend
- 25 Jun, 2022
- 26 Mins read
Introduction
All code from this tutorial as a complete package is available in this repository. If you find this tutorial helpful, please share it with your friends and colleagues, and make sure to star the repository.
Since the ECMAScript JavaScript Standard is revised annually, it is a good idea to update our code as well.
The most recent JavaScript standards are occasionally incompatible with the browser. Something like to babel, which is nothing more than a JavaScript transpiler, is what we need to fix this sort of issue.
So, in this little tutorial, I’ll explain how to set up babel for a basic NodeJS Express application so that we may utilize the most recent ES6 syntax in it.
What is Babel?
Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in current and older browsers or environments. Here are the main things Babel can do for you:
- Transform syntax
- Polyfill features that are missing in your target environment (through a third-party polyfill such as core-js)
- Source code transformations (codemods)
Project Setup
We’ll begin by creating a new directory called backend-template
and then we’ll create a new package.json
file. We’re going to be using yarn for this example, but you could just as easily use NPM if you choose, but yarn is a lot more convenient.
Engine Locking
The same Node engine and package management that we use should be available to all developers working on this project. We create two new files in order to achieve that:
.nvmrc
: Will disclose to other project users the Node version that is being utilized..npmrc
: reveals to other project users the package manager being used.
Notably, the usage of engine-strict
said nothing about yarn
in particular; we handle that in packages.json
:
open packages.json
add the engines
:
Babel Setup
In order to set up babel in the project, we must first install three main packages.
babel-core
: The primary package for running any babel setup or configuration is babel-core.babel-node
: Any version of ES may be converted to ordinary JavaScript using the babel-node library.babel-preset-env
: This package gives us access to forthcoming functionalities that node.js does not yet comprehend. New features are constantly being developed, thus it will probably take some time for NodeJS to incorporate them.
Babel is mostly used in the code base to take advantage of new JavaScript capabilities. Unless the code is pure JavaScript, we don’t know if the server’s NodeJS will comprehend the specific code or not.
Therefore, transiling the code before deployment is usually advised. Two different types of babel transpiling code exist.
Development Setup:
Here, we initialize the package.json and install the basic express server, mongoose, cors, dotenv, babel-core, babel-node, babel-preset-env, babel-plugin-module-resolver.
Babel Configration
After that, we need to create a file called .babelrc
in the project’s root directory, and we paste the following block of code there.
Code Formatting and Quality Tools
We will be using two tools in order to establish a standard that will be utilized by all project participants to maintain consistency in the coding style and the use of fundamental best practices:
- Prettier: A tool that will help us to format our code consistently.
- ESLint: A tool that will help us to enforce a consistent coding style.
Prettier
Prettier will handle the automated file formatting for us. Add it to the project right now.
It’s only needed during development, so I’ll add it as a devDependency
with -D
Additionally, I advise getting the Prettier VS Code extension so that you may avoid using the command line tool and have VS Code take care of the file formatting for you. It’s still required to include it here even when it’s installed and set up in your project since VSCode will utilize your project’s settings.
We’ll create two files in the root:
.prettierrc
: This file will contain the configuration for prettier..prettierignore
: This file will contain the list of files that should be ignored by prettier.
I’ve listed the folders in that file that I don’t want Prettier to waste any time working on. If you’d want to disregard specific file types in groups, you may also use patterns like *.html.
Now we add a new script to package.json
so we can run Prettier:
You can now run yarn prettier
to format all files in the project, or yarn prettier:check
to check if all files are formatted correctly.
to automatically format, repair, and save all files in your project that you haven’t ignored. My formatter updated around 7 files by default. The source control tab on the left of VS Code has a list of altered files where you may find them.
ESLint
We’ll begin with ESLint, which is a tool that will help us to enforce a consistent coding style, at first need to install the dependencies.
We’ll create two files in the root:
.eslintrc
: This file will contain the configuration for ESLint..eslintignore
: This file will contain the list of files that should be ignored by ESLint.
Now we add a new script to package.json
so we can run ESLint:
You can test out your config by running:
You can now run yarn lint
to format all files in the project, or yarn lint:check
to check if all files are formatted correctly.
Setup logger for development
I had a problem setting up the logger when constructing a server-side application based on Node and Express router. Conditions for the answer:
- Logging application event
- Ability to specify multiple logs level
- Logging of HTTP requests
- Ability to write logs into a different source (console and file)
I found two possible solutions:
- Morgan: HTTP logging middleware for express. It provides the ability to log incoming requests by specifying the formatting of log instance based on different request related information.
- Winston: Multiple types of transports are supported by a lightweight yet effective logging library. Because I want to simultaneously log events into a file and a terminal, this practical feature is crucial for me.
I’ll use Winston for the logging, first I’ll install the package:
Then I’ll create a file called utils/logger.util.js
in it:
Build file structure and basic express application
at first we’ll create a directory called src
, and we’ll build the file structure inside of it.
for robust and don’t repeat some text we’ll create constants files in the constants
directory:
there are some constants that are used in the application, but that are not related to the application itself. For example, the constants that are used in the API are in the api.constant.js
file, and there is a file that provides freely for HTTP codes and replies, but we’ll make one from start.
and we’ll add to other constants in the future.
after creating the directory structure, we’ll create a file called .env
and .env.example
in the root directory:
.env
: This file will contain the configuration for the application..env.example
: is the file that contains all of the configurations for constants that.env
has, but without values; only this one is versioned.env.example
serves as a template for building a.env
file that contains the information required to start the program.
Now we add a new variable to .env
:
after creating the directory structure and .env
files, we’ll create a file called index.js
, bin/www.js
, config/db.config.js
and env/variable.env.js
in the src
directory.
new files will be created in the src
directory, and we’ll add the following code to each of them:
Now we add a new script to package.json
so we can run the application:
New you can run the application with yarn start
or yarn dev
, and you can also run the application with yarn build
to create a production version.
New we’ll add a new package:
compression: Your Node.js app’s main file contains middleware for compression
. GZIP, which supports a variety of compression
techniques, will then be enabled. Your JSON response and any static file replies will be smaller as a result.
cookie-parser: Your Node.js app’s main file contains middleware for cookie-parser
. This middleware will parse the cookies in the request and set them as properties of the request object.
core-js: Your Node.js app’s main file contains middleware for core-js
. This middleware will add the necessary polyfills to your application.
helmet: Your Node.js app’s main file contains middleware for helmet
. This middleware will add security headers to your application.
regenerator-runtime: Your Node.js app’s main file contains middleware for regenerator-runtime
. This middleware will add the necessary polyfills to your application.
we’ll change the index.js
file:
and we’ll change the bin/www.js
file:
new we’ll run the application with yarn dev
:
Git Hooks
Before moving on to component development, there is one more section on configuration. If you want to expand on this project in the future, especially with a team of other developers, keep in mind that you’ll want it to be as stable as possible. To get it right from the beginning is time well spent.
We’re going to use a program called Husky.
Husky
Husky is a tool for executing scripts at various git stages, such as add, commit, push, etc. We would like to be able to specify requirements and, provided our project is of acceptable quality, only enable actions like commit and push to proceed if our code satisfies those requirements.
To install Husky run
This will create a .husky
directory in your project. Your hooks will be located here. As it is meant for other developers as well as yourself, make sure this directory is included in your code repository.
A .husky
directory will be created in your project by the second command. Your hooks will be located here. As it is meant for other developers as well as yourself, make sure this directory is included in your code repository.
Add the following script to your package.json
file:
This will ensure Husky gets installed automatically when other developers run the project.
To create a hook run:
The aforementioned states that the yarn lint
script must run and be successful before our commit may be successful. Success here refers to the absence of mistakes. You will be able to get warnings (remember in the ESLint config a setting of 1 is a warning and 2 is an error in case you want to adjust settings).
We’re going to add another one:
This makes sure that we can’t push to the remote repository until our code has built correctly. That sounds like a very acceptable requirement, don’t you think? By making this adjustment and attempting to push, feel free to test it.
Commitlint
Finally, we’ll add one more tool. Let’s make sure that everyone on the team is adhering to them as well (including ourselves! ), since we have been using a uniform format for all of our commit messages so far. For our commit messages, we may add a linter.
We will configure it using a set of common defaults, but since I occasionally forget what prefixes are available, I like to explicitly provide that list in a commitlint.config.js
file:
Afterward, use Husky to enable commitlint by using:
Know connected this repository with GitHub, you can now push your commits to GitHub.
VS Code
Configuration
We can now take advantage of some useful VS Code functionality to have ESLint and Prettier run automatically since we have implemented them.
Make a settings.json
file and a directory called .vscode
at the top of your project. This will be a list of values that overrides the VS Code installation’s default settings.
Because we may set up particular parameters that only apply to this project and share them with the rest of our team by adding them to the code repository, we want to put them in a folder for the project.
Within settings.json
we will add the following values:
settings.json
Debugging
In case we encounter any problems while developing our program, let’s set up a handy environment for debugging.
Inside of your .vscode
directory create a launch.json
file:
Authentication
Authentication Setup
We’ll add a new packages to our project:
- crypto-js: A JavaScript library for encryption and decryption.
- jsonwebtoken: A JavaScript library for creating and verifying JSON Web Tokens.
add secret key to .env
file:
add JWT_SECRET
and PASS_SECRET
to variable.env.js
file:
know we’ll add the constants to:
Authentication Middleware
Authentication Security
Authentication validations
Authentication schemas
Authentication Models
Authentication Repositories
Authentication Services
Authentication Controllers
auth.controller.js
user.controller.js
Authentication Routes
auth.router.js
user.router.js
edit index.js
Summary
Finally, after compilation, we can now need to deploy the compiled version in the NodeJS production server.
All code from this tutorial as a complete package is available in this repository.