#100DaysOfMERN - Day 34

Subscribe to my newsletter and never miss my upcoming articles

✏ The Node process Object

I've used the Node process object a couple of times before in my code, but never did a deeper dig into what this object actually is.

In short - it's one of Node's very few globals. It holds information about the current runtime, and also comes with some methods like process.exit() or process.nextTick() (find a full list in Node's documentation)

To inspect and play around with it, you can access it directly from the command line by using a -p flag:

node -p "process.versions"

However, I'm going to add a file testprocess.js to the root directory of one of my projects, and add a script to call it in the package.json:

package.json

"scripts": {
        "test": "node testprocess.js"
    }

For now, I'll only log the process object:

testprocess.js

console.log(process);

Running it:

npm run test

This will print the whole object with a LONG list of properties and methods to the console. I'm not sure if it's necessary to learn about them all at this point, but some of those are worth knowing.

I've already experimented with process.nextTick() at the very beginning on Day 8, when I learned about the event loop, but today I'll focus more on the properties and methods that I will likely be using in a MERN application.

process.exit(code)

This will terminate the execution with a status code. The default is 0 (normal exit, no errors), find a list of all exit codes here.

You can either call that method explicitly, or otherwise - if no more tasks are scheduled in a script and the event loop is empty, Node will exit the process with 0. You can listen for this event and still run synchronous code before termination:

process.on('exit', code => {
    console.log(`about to exit with code ${code}`);
});

This however will not work, because setTimeout is async:

process.on('exit', () => {
    setTimeout(() => console.log('I will never log'), 0);
});

There's another event beforeExit though, that can still run async operations (unless the script is terminated by calling .exit() explicitly - in which case beforeExit won't fire). But note that the below is a bad idea:

// very bad idea
process.on('beforeExit', () => {
    setTimeout(() => console.log('I WILL KEEP THE PROCESS RUNNING FOREVER'), 0);
});

process.env

process.env has a lot of information about the environment:

  • operating system
  • processors
  • computer name and user name
  • system root directory
  • location of node / node.exe

... and tons of other stuff.

You can also set your own environment variables by including a .env file in your project root directory (as described on Day 33). The connection string to your database or any API keys you're using are examples for what you'd like to store in your environment variables, instead of plainly putting those into your source code (and pushing them to github).

process.argv

This is an array containing the command line arguments when the process was launched. The first entry is the path to node.exe on your system. The second is the path to the file that was executed. The following elements will hold any additional arguments.

To test, add another script to the package.json, where you run the file with an additional argument -t

"scripts": {
        "test": "node testprocess.js",
        "testarg": "node testprocess.js -t"
    }

testprocess.js

console.log(`argv0: ${process.argv[0]}`); // C:\Program Files\nodejs\node.exe
console.log(`argv1: ${process.argv[1]}`); // C:\path\to\testprocess.js
console.log(`argv2: ${process.argv[2]}`); // -t

This allows you to run some conditional logic in a script, depending on what argument you add when calling it, for example:

if (process.argv[2] === '-d') {
    // delete the whole database 
} else {
    // fill database with data
}

✏ Use case for process.exit(): A simple Script to save to MongoDB

Each time I publish a blog post, I also need to update the database for my #100DaysOfMERN App, where I keep track of all posts and a list of tags for each post.

I could do that by opening MongoDB Compass and inserting the new post record and its data manually over the GUI, but I'd like to do that programmatically instead, and run a script for this.

I've added a file addpost.js to my backend folder, where I can open a connection to the database, and insert (save) a new post. Node will not exit the script in this case, so I'll do that manually after saving the new post:

const dotenv = require('dotenv');
dotenv.config();

const connDB = require('./db/connect.js');


const Post = require('./models/postmodel.js');

const newPost = new Post({
    title: 'Day 34',
    tags: ['100daysofmern app', 'node', 'process', 'mongodb', 'mongoose'],
    summary: [''],
    published: '2021/02/22',
    slug: '/100daysofmern-day-34'
});

connDB()
    .then(() => newPost.save())
    .then(() => {
        console.log('post added');
        process.exit();
    })
    .catch(err => console.log('error in addpost.js: ', err));

✏ Recap

I've learned

  • more about the node process object
  • how to write code that results in node never exiting (not good)
  • how to feed my database with a script

✏ Thanks for reading!

I do my best to thoroughly research the things I learn, but if you find any errors or have additions, please leave a comment below, or @ me on Twitter. If you liked this post, I invite you to subsribe to my newsletter. Until next time 👋


✏ Previous Posts

You can find an overview of all previous posts with tags and tag search here:

#100DaysOfMERN - The App

No Comments Yet