JavaScript에서 Node.js로: 무대 뒤에서 실제로 일어나는 일 이해하기 (4.1부)

작성자

카테고리:

← 피드로
DEV Community · Sudhanshu code · 2026-07-24 개발(SW)

Node.js Modules Explained from Scratch — Why Do Modules Even Exist?

If you’ve been writing Node.js for even a few days, you’ve probably seen code like this:

const fs = require(“fs”);
const express = require(“express”);
const path = require(“path”);

Or maybe you’ve written your own module:

const math = require(“./math”);

Most tutorials stop here.

They teach how to use require(), but very few explain why modules exist in the first place.

In this article, we’re not going to start with require().

Instead, we’re going to start with a much more fundamental question.

Why were modules invented at all?

Because once you understand that, everything else in Node.js modules starts making sense.

Imagine Building Everything in One File

Let’s say you’re creating a banking application.

At first, everything feels simple.

function login() {}

function logout() {}

function transferMoney() {}

function checkBalance() {}

function createAccount() {}

function updateProfile() {}

function deleteAccount() {}

function sendOTP() {}

function generateToken() {}

function connectDatabase() {}

Looks manageable.

Now imagine your application grows.

After six months, your file contains:

Authentication
Database Logic
Payment Logic
Email Service
Notifications
User Management
Admin Dashboard
Reports
Logging
Validation
Utility Functions

One file becomes

app.js

25,000 lines

Can one developer understand it easily?

No.

Can ten developers work on the same file?

Also no.

Can bugs be found quickly?

Again, no.

So the problem wasn’t JavaScript.

The problem was organization.

Software Is Built by Teams

Modern software isn’t written by one person.

Imagine a company with 40 backend engineers.

If everyone edits the same file…

app.js

chaos begins.

Developer A changes authentication.

Developer B edits payments.

Developer C modifies notifications.

Developer D updates database code.

Soon everyone is editing the same file.

Conflicts become unavoidable.

Software engineering needed a better way to organize code.

That idea became modules.

What Is a Module?

The simplest definition is:

A module is a self-contained piece of code responsible for one specific task.

Instead of writing everything together…

we divide the application into small independent files.

Example:

project/

├── app.js

├── auth.js

├── payment.js

├── database.js

├── email.js

├── utils.js

└── logger.js

Every file has a single responsibility.

This makes applications easier to understand, test, debug, and maintain.

Modules Are Not a Node.js Feature

This surprises many beginners.

People often say:

“Modules are a Node.js concept.”

Not exactly.

The idea of modules is much older than Node.js.

Many programming languages support modular programming.

Examples include:

Java Packages
Python Modules
C Libraries
C++ Header Files
Rust Crates
Go Packages

Node.js adopted this idea for JavaScript.

JavaScript Before Modules

When JavaScript was created in 1995…

there were no modules.

The language was designed to make web pages interactive.

Most websites contained only a few lines of JavaScript.

For example:

alert(“Welcome”);

or

button.onclick = function () {
alert(“Clicked”);
};

Nobody imagined JavaScript would one day power:

Netflix
PayPal
LinkedIn
Uber
VS Code
Discord

Because applications were tiny…

modules weren’t considered necessary.

Then JavaScript Started Growing

Around the mid-2000s, developers started building larger web applications.

Instead of

200 lines

applications became

20,000 lines

50,000 lines

100,000+ lines

Developers desperately needed code organization.

But JavaScript still had no official module system.

People started inventing their own solutions.

Before Node.js, Developers Used the Global Scope

Suppose you have two files.

math.js

function add(a, b) {
return a + b;
}

app.js

console.log(add(2,3));

Seems fine.

Until another developer writes

function add() {}

in another file.

Now both functions exist globally.

Which one should JavaScript use?

Nobody knows.

This became known as Global Namespace Pollution.

Everything lived in one shared global environment.

Large applications became difficult to maintain.

The Global Scope Problem

Imagine one whiteboard shared by an entire company.

Everyone writes on the same board.

Soon:

names collide
variables overwrite each other
debugging becomes painful
maintenance becomes difficult

The JavaScript global scope behaved similarly.

Modules solved this problem.

How Modules Solve the Problem

Instead of one giant shared environment…

every file receives its own private scope.

Imagine:

math.js

Private Room
auth.js

Private Room
database.js

Private Room

Each file can safely define:

const PORT = 3000;

without affecting another file.

This isolation is one of the biggest advantages of modules.

Every File Is a Module in Node.js

One of the most beautiful design decisions in Node.js is incredibly simple.

Every JavaScript file is automatically treated as a separate module.

Suppose we have:

project/

├── app.js

└── math.js

math.js

const PI = 3.14159;

function add(a, b) {
return a + b;
}

At first glance, you might expect both PI and add() to be available everywhere.

They are not.

Open another file.

app.js

console.log(PI);

Output:

ReferenceError: PI is not defined

Why?

Because every file has its own scope.

This is one of Node.js’s most important design decisions.

Why Doesn’t One File See Another File’s Variables?

Think about a house.

Every room has its own door.

Just because your bedroom contains a table…

doesn’t mean the kitchen automatically has access to it.

Node.js modules work similarly.

Each file is isolated.

Nothing leaves that file unless you explicitly allow it.

That is where module.exports enters the picture.

We’ll study that in the next article.

How Does Node Know a File Is a Module?

This is where things become interesting.

When Node loads

math.js

it does not execute the file exactly as you wrote it.

Internally…

Node wraps your code before executing it.

Something similar to this happens behind the scenes:

(function (exports, require, module, __filename, __dirname) {

// Your code lives here

Enter fullscreen mode Exit fullscreen mode

});

This is called the Module Wrapper Function.

We’ll explore it deeply in Part 4.2.

For now, remember one important idea:

Every file receives its own private execution environment.

That single design decision solves a huge number of software engineering problems.

Benefits of Modules

Modules provide much more than cleaner code.

They enable:

Better code organization
Reusability
Encapsulation
Easier testing
Team collaboration
Maintainability
Separation of concerns
Reduced naming conflicts
Improved scalability

These principles apply across almost every modern programming language.

Key Takeaways

After reading this article, you should understand that:

Modules were created to solve software organization problems.
JavaScript originally had no module system.
Large applications exposed the limitations of the global scope.
Node.js treats every JavaScript file as a separate module.
Every module has its own private scope.
Variables inside one file are not automatically visible in another.
Node internally wraps every module before executing it.
This wrapper creates isolation and lays the foundation for require() and module.exports.
Coming Next

In Part 4.2, we’ll open the black box and answer questions that almost every Node.js developer asks:

What actually happens when you write require(“./math”)?
Is require() part of JavaScript or Node.js?
What is the Module Wrapper Function?
Why do exports and module.exports exist?
How does one module communicate with another?
What does Node execute behind the scenes before your code runs?

We’ll move from using modules…

to understanding how Node.js builds its entire module system internally.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다