Bird
Raised Fist0
Node.jsframework~8 mins

CommonJS require and module.exports in Node.js - Performance & Optimization

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Performance: CommonJS require and module.exports
MEDIUM IMPACT
This concept affects server-side module loading speed and initial script execution time in Node.js environments.
Loading modules in a Node.js application
Node.js
import fs from 'fs/promises';
async function readFile() {
  const data = await fs.readFile('file.txt');
  console.log(data.toString());
}
readFile();
Using ES modules with async file read avoids blocking, improving startup and responsiveness.
📈 Performance GainNon-blocking module loading and file reading, reducing startup delay and improving event loop availability.
Loading modules in a Node.js application
Node.js
const fs = require('fs');
const data = fs.readFileSync('file.txt');
console.log(data.toString());
Synchronous require and file read block the event loop, delaying startup and responsiveness.
📉 Performance CostBlocks event loop during require and file read, increasing startup time by tens of milliseconds depending on file size.
Performance Comparison
PatternModule LoadingEvent Loop BlockingStartup DelayVerdict
CommonJS require with sync operationsSynchronousBlocks event loopHigh delay[X] Bad
ES modules with async operationsAsynchronousNon-blockingLow delay[OK] Good
Rendering Pipeline
In Node.js, CommonJS require synchronously loads and executes modules before continuing, blocking the event loop and delaying script execution.
Module Loading
Script Execution
Event Loop
⚠️ BottleneckSynchronous module loading blocks the event loop, delaying all subsequent code execution.
Optimization Tips
1Avoid synchronous require calls during startup to prevent blocking the event loop.
2Prefer ES modules with asynchronous imports for better startup performance.
3Use Node.js profiling tools to detect blocking synchronous operations.
Performance Quiz - 3 Questions
Test your performance knowledge
What is the main performance drawback of using CommonJS require in Node.js?
AIt blocks the event loop during module loading.
BIt increases network latency for HTTP requests.
CIt causes excessive memory usage.
DIt slows down CSS rendering in browsers.
DevTools: Node.js --inspect with Chrome DevTools Performance panel
How to check: Run Node.js with --inspect flag, open Chrome DevTools, record performance during startup, and look for long blocking tasks.
What to look for: Look for long 'Script Evaluation' or 'Blocking' tasks indicating synchronous require or blocking operations.

Practice

(1/5)
1. What does module.exports do in a Node.js file?
easy
A. It deletes the current module from memory.
B. It imports code from another module.
C. It runs the module as a standalone program.
D. It defines what the module shares when required by another file.

Solution

  1. Step 1: Understand module.exports role

    module.exports sets the object or value that other files receive when they use require() on this module.
  2. Step 2: Differentiate from require()

    require() is used to import, while module.exports is used to export code from a module.
  3. Final Answer:

    It defines what the module shares when required by another file. -> Option D
  4. Quick Check:

    module.exports = export code [OK]
Hint: Remember: module.exports shares, require() imports [OK]
Common Mistakes:
  • Confusing require() with module.exports
  • Thinking module.exports runs code
  • Assuming module.exports deletes modules
2. Which of the following is the correct syntax to import a local module named utils.js using CommonJS?
easy
A. const utils = require('./utils');
B. const utils = require('utils');
C. import utils from './utils';
D. const utils = import('./utils');

Solution

  1. Step 1: Identify local module import syntax

    Local files require a relative path starting with './' or '../' in require().
  2. Step 2: Check each option

    const utils = require('./utils'); uses require('./utils'), which correctly imports the local utils.js file. const utils = require('utils'); misses './', so it looks for a package. import utils from './utils'; uses ES module syntax, not CommonJS. const utils = import('./utils'); uses dynamic import, not CommonJS.
  3. Final Answer:

    const utils = require('./utils'); -> Option A
  4. Quick Check:

    Local modules need './' in require() [OK]
Hint: Use './' prefix for local files in require() [OK]
Common Mistakes:
  • Omitting './' for local modules
  • Using ES module import syntax in CommonJS
  • Using import() instead of require()
3. Given the following two files, what will be logged when node app.js runs?

// math.js
module.exports.add = (a, b) => a + b;
module.exports.sub = (a, b) => a - b;

// app.js
const math = require('./math');
console.log(math.add(5, 3));
console.log(math.sub(5, 3));
medium
A. undefined and undefined
B. 8 and 2
C. Error: add is not a function
D. 5 and 3

Solution

  1. Step 1: Understand exports in math.js

    math.js exports two functions: add and sub, which add and subtract two numbers.
  2. Step 2: Trace app.js calls

    app.js requires math.js and calls math.add(5, 3) which returns 8, and math.sub(5, 3) which returns 2.
  3. Final Answer:

    8 and 2 -> Option B
  4. Quick Check:

    5+3=8 and 5-3=2 [OK]
Hint: Check exported function names and call with correct args [OK]
Common Mistakes:
  • Expecting undefined because of wrong export syntax
  • Confusing module.exports with exports shorthand
  • Forgetting to require the module
4. What is the error in the following code snippet?

// greet.js
exports = function() { return 'Hello'; };

// app.js
const greet = require('./greet');
console.log(greet());
medium
A. Cannot find module './greet'.
B. SyntaxError due to missing module.exports.
C. greet is not a function because exports was overwritten incorrectly.
D. No error; it logs 'Hello'.

Solution

  1. Step 1: Analyze exports assignment in greet.js

    Assigning directly to exports replaces the local exports variable but does not change module.exports, so require() gets an empty object.
  2. Step 2: Understand require() result in app.js

    Since module.exports was not changed, greet is an empty object, not a function, so calling greet() causes an error.
  3. Final Answer:

    greet is not a function because exports was overwritten incorrectly. -> Option C
  4. Quick Check:

    Overwrite exports breaks module.exports [OK]
Hint: Always assign to module.exports, not exports directly [OK]
Common Mistakes:
  • Assigning function directly to exports instead of module.exports
  • Expecting exports and module.exports to be the same after reassignment
  • Ignoring that require() returns module.exports
5. You want to export a single class from a module so that requiring it returns the class directly. Which is the correct way to do this in CommonJS?

class User {
  constructor(name) {
    this.name = name;
  }
}

// What should you write here?
hard
A. module.exports = User;
B. exports.User = User;
C. module.exports.User = User;
D. export default User;

Solution

  1. Step 1: Understand exporting a single value

    To export a single class so require() returns it directly, assign it to module.exports.
  2. Step 2: Compare options

    module.exports = User; assigns User directly to module.exports, so require('./module') returns the class. module.exports.User = User; and exports.User = User; export an object with User property, so require() returns an object, not the class itself. export default User; uses ES module syntax, invalid in CommonJS.
  3. Final Answer:

    module.exports = User; -> Option A
  4. Quick Check:

    Single export = module.exports = value [OK]
Hint: Assign single export directly to module.exports [OK]
Common Mistakes:
  • Using exports.User instead of module.exports for single export
  • Mixing ES module syntax with CommonJS
  • Expecting require() to return class when exporting as property