File Structure of a Node Project
Tags: node, javascript
Published: 2020-09-21 14:10:34

In this article I am going to share the details about the structure of a Node project which could be maintained during the development for easier identification and better understanding.
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/2f342bat9knd74ox7h52.jpeg)

## 1. package.json
```
{
  "name": "node",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node src/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  }
}
```
* package.json is a mandatory file present in the root directory of the project

* package.json holds all the metadata and dependencies required for a project. It can be created by running the following command in the root directory

```
 npm init -y
```

-y specifies do not ask me any question simply create the file.

* you can specify the script which should be executed for starting the node project in scripts -> start and for stopping in scripts -> stop 
```
"scripts": {
    "start": "node src/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  }
```
and simply start and stop the node project using 
```
npm start
npm stop
```
* To install all the required node dependancies in package.json 
```
sudo npm install
```

If **Error: EACCES: permission denied** error occurs
```
sudo npm install -g --unsafe-perm=true --allow-root
```

#2. .env
* .env file contains all the environment variables required for a project
```
APP_NAME = node-project
NODE_ENV = development
PORT = 3003
JWT_SECRET = '$2a$0sdfwewewerbN2Jf2UcG'
JWT_KEY = 'ewrwetiLCJjb21wYW55IjoiQWlyN3NlYXMtwetPpcuKZCtFE4k'
LOCAL_DB_URI = mongodb://localhost:27017/db_api
SERVER_DB_URI = mongodb+srv://cezDbAdmin:cezDbAsdd@development-we.gcp.mongodb.net(opens in new tab)/cdez?retryWrites=true&w=majority

CONTACT_API_HOOK = http://api.node-app.dev/contactserver/api/v1
CONTACT_API_HOOK1 = http://127.0.0.1:3003/contactserver/api/v1

ALERT_MAIL = 'noreply@gmail.com(opens in new tab)'
FIREBASE_REDIRECT_URL='http://localhost:8080/dashboard'

MAIL_API_HOOK = http://api.node-project.dev/mailserver/api/v1
ALERT_MAIL='Node project <alerts@node-project.com>'
```
# 3. server.js
* server.js is the file which will be executed first in a node project. If you are using mongoDB the promise for the DB connection should be established here.
```
export const start = () => {
  init()
    .then(app => {
      app.listen(port, () => {
        let server =
          (env === "secure" ? "https://" : "http://") + host + ":" + port;
        console.log(
          chalk.green("Development server started on " + server)
        );
      });
    })
    .catch(err => {
      console.error(err);
    });
};

module.exports = start();
```
#4. .gitignore
* git ignore file should contain the list of files that should not be committed in a git push. 
```
/node_modules
/public/hot
/public/storage
/storage/*.key
/.idea
/.vagrant
/.vscode
npm-debug.log
yarn-error.log
.env
```
#5. index.js

index.js is most likely the entry point for requiring a module. In Node.js, Node itself is the web server so you don't need to name anything index.js but it's easier for people to understand which file to run first.

index.js typically handles your app startup, routing and other functions of your application and does require other modules to add functionality. If you're running a website or web app it would also handle become a basic HTTP web server.
```
let express = require('express')
let app = express()

let personRoute = require('./routes/person')
app.use(personRoute)
app.use(express.static('public'))

const PORT  = process.env.PORT || 3050
app.listen(PORT,()=> console.info(`Server has started on ${PORT}`))
```

#6. app
* The app folder should contain all the files of the project in an orderly format. The files should be organised into folders such as
    * **Routers** : Which contains all the files related to routing Ex: AuthRouter.js
```
import Router from "koa-router";
import RoleController from "../controllers/RoleController";
import Authentication from "../Process/Authentication"

const router = new Router();

router.prefix("/iamserver/api/v1");
router
.use(Authentication.authorize)
.post("/roles", RoleController.create)
.put("/roles/:role", RoleController.update)
.delete("/roles/:role", RoleController.destroy)
export default router;
```

   * **Controllers** : should receive all the routing from routers Ex: RoleController.js
```
"use strict";
import Controller from "../../Controller";
import Company from "../models/Company"

class RoleController extends Controller {
    
        async getCompanies(ctx){
            try {                
                ctx.body = await Company.allCompanies()
            }
            catch (err) {
                ctx.throw(err)
            } 
        } 
    }
    
    export default new RoleController();
```
   * **Models** : Files in this folder should contain the entity related operation such as accessing DB, processing based on business logic. Ex : Company.js
```
import CompanySchema from "../../database/schema/CompanySchema";

class Company extends Database {
    constructor() {
        super(CompanySchema);
    }
    async allCompanies(){
        return  this.model.find().populate('users')
    }
}

export default new Company();
```