CommonJS Modules

Loading concept...

CommonJS Modules: Building with LEGO Blocks

The Big Idea

Imagine you have a giant LEGO castle to build. Would you try to build it all in one go? That would be crazy! Instead, you’d build smaller pieces—a tower here, a wall there, a gate over there—and then snap them together.

That’s exactly what CommonJS modules do for your code. They let you break your program into small, reusable pieces that click together perfectly.


🏗️ The CommonJS Module System

Think of CommonJS like a LEGO instruction manual that Node.js follows. It tells Node.js:

  1. How to package a piece of code (like putting LEGO bricks in a box)
  2. How to share that code with others (like handing the box to a friend)
  3. How to use someone else’s code (like opening their box and using their bricks)

Every .js file in Node.js is automatically a module. It’s like every file comes in its own little box!

// greet.js - This file is a module!
// It's like a small LEGO kit
const greeting = "Hello, friend!";

📦 The require Function: Opening the Box

The require function is like opening a LEGO box. You tell it which box you want, and it gives you what’s inside.

// main.js
const greet = require('./greet');
// "Hey Node, open the 'greet' box for me!"

Three Types of Boxes You Can Open

graph TD A[require] --> B[Your Files] A --> C[Built-in Modules] A --> D[npm Packages] B --> E["require#40;'./myfile'#41;"] C --> F["require#40;'fs'#41;"] D --> G["require#40;'express'#41;"]

Your own files: Start with ./ or ../

const helper = require('./helpers/math');

Built-in modules: Just use the name

const fs = require('fs');
const path = require('path');

npm packages: Just use the name (after installing)

const express = require('express');

🎁 The module Object: Your Shipping Box

Every file has a special object called module. Think of it as the shipping box for your code. It holds important information about your file.

// Inside any file, you can see:
console.log(module);

// Shows something like:
// {
//   id: '.',
//   path: '/home/user/project',
//   exports: {},    <-- The stuff you're sharing!
//   filename: '/home/user/project/app.js',
//   loaded: false,
//   children: [],
//   paths: [...]
// }

The most important part? module.exports — that’s what you put IN the box to share!


🎯 module.exports vs exports: Two Ways to Pack

Here’s where it gets fun. You have two ways to pack things into your shipping box.

Way 1: Replace the Whole Box (module.exports)

// calculator.js
function add(a, b) {
    return a + b;
}

// Replace the entire box with this function
module.exports = add;
// main.js
const add = require('./calculator');
console.log(add(2, 3)); // 5

Way 2: Add Items to the Box (exports)

// mathTools.js
exports.add = (a, b) => a + b;
exports.subtract = (a, b) => a - b;
exports.multiply = (a, b) => a * b;
// main.js
const math = require('./mathTools');
console.log(math.add(2, 3));      // 5
console.log(math.subtract(5, 2)); // 3

The Golden Rule

exports is just a shortcut pointing to module.exports. They start as the same box!

graph LR A[exports] -->|points to| B[module.exports] B -->|is what gets| C[shipped out]

But watch out! If you replace exports entirely, you break the link:

// ❌ WRONG - This breaks the connection!
exports = { name: "broken" };
// Nothing gets exported!

// ✅ RIGHT - Replace module.exports instead
module.exports = { name: "working" };

Quick Comparison

What You Want Use This
Export ONE thing (function, class) module.exports = thing
Export MANY things exports.name = thing
Export an object with methods Either works!

⏰ Require Execution Timing: When Does the Magic Happen?

Here’s something cool: when you require a file, Node.js runs that file immediately!

// logger.js
console.log("Logger is loading...");
const startTime = new Date();

module.exports = {
    log: (msg) => console.log(`[LOG] ${msg}`),
    getStartTime: () => startTime
};

console.log("Logger is ready!");
// main.js
console.log("Before requiring logger");
const logger = require('./logger');
console.log("After requiring logger");
logger.log("Hello!");

Output:

Before requiring logger
Logger is loading...
Logger is ready!
After requiring logger
[LOG] Hello!

The Caching Superpower

Node.js is smart! It remembers modules after loading them once:

// first require - runs the file
const a = require('./helper');

// second require - uses cached version!
const b = require('./helper');

// a and b are the SAME object!
console.log(a === b); // true
graph TD A[First require] --> B[Load & Run File] B --> C[Store in Cache] D[Second require] --> C C --> E[Return Same Object]

This means:

  • Your module code runs only once
  • All requires get the same instance
  • It’s fast and memory-efficient!

🔍 require.main: “Am I the Star of the Show?”

Sometimes a file needs to know: “Am I being run directly, or am I just being required by someone else?”

It’s like asking: “Am I the main actor, or am I a supporting character?”

// server.js
function startServer() {
    console.log("Server starting on port 3000...");
}

function getConfig() {
    return { port: 3000 };
}

// If THIS file is run directly...
if (require.main === module) {
    // I'm the star! Start the server!
    startServer();
} else {
    // I'm supporting. Just export my tools.
    console.log("Loaded as a module");
}

module.exports = { startServer, getConfig };

When you run directly:

node server.js
# Output: Server starting on port 3000...

When you require it:

// app.js
const server = require('./server');
// Output: Loaded as a module

// Now you can use the exports
server.startServer(); // Start manually when ready

Why Is This Useful?

graph TD A[Your File] --> B{require.main === module?} B -->|Yes - Run Directly| C[Execute Main Logic] B -->|No - Required| D[Just Export Tools]

Common uses:

  • Testing: Run tests when file is executed directly
  • CLI tools: Start the app when run from command line
  • Libraries: Just export functions when required
// utils.js
function greet(name) {
    return `Hello, ${name}!`;
}

module.exports = { greet };

// Demo when run directly
if (require.main === module) {
    console.log(greet("World"));
    console.log("Utils demo complete!");
}

🎯 Putting It All Together

Let’s build a tiny app using everything we learned!

// config.js
console.log("Loading config...");

module.exports = {
    appName: "My Cool App",
    version: "1.0.0"
};
// greet.js
exports.hello = (name) => `Hello, ${name}!`;
exports.goodbye = (name) => `Goodbye, ${name}!`;
// app.js
const config = require('./config');
const { hello, goodbye } = require('./greet');

console.log(`Welcome to ${config.appName}`);
console.log(hello("Developer"));
console.log(goodbye("Developer"));

if (require.main === module) {
    console.log("App finished running!");
}

Output:

Loading config...
Welcome to My Cool App
Hello, Developer!
Goodbye, Developer!
App finished running!

🌟 Key Takeaways

  1. CommonJS = Node.js’s way of organizing code into modules
  2. require() = Opens another file and gets what it exports
  3. module = Your file’s info box with exports inside
  4. module.exports = What you share (replaces entire export)
  5. exports = Shortcut to add properties (don’t reassign!)
  6. Execution timing = Code runs immediately when required, then cached
  7. require.main = Check if file is run directly or required

You now understand how Node.js modules work! Like LEGO blocks, you can build amazing things by snapping small, focused pieces together. Happy coding! 🚀

Loading story...

No Story Available

This concept doesn't have a story yet.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Interactive Content

This concept doesn't have interactive content yet.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Cheatsheet Available

This concept doesn't have a cheatsheet yet.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

No Quiz Available

This concept doesn't have a quiz yet.