Files are modules
Private by default — that's the whole idea.
- Every
.jsfile in Node is its own module. - Variables + functions are scoped to that file; they never leak unless exported.
- Calling an unexported function from another file →
ReferenceError. - Private-by-default is a feature: no naming collisions, cleaner refactors.
The bridge — exports + require
Sender and receiver.
- Sender:
module.exports = something— whatever you assign becomes this module’s public API. - Receiver:
const x = require("./path")— runs the file, returnsmodule.exports. - Default
module.exportsis{}(an empty object). - The
.jsextension is optional:require("./sum")works.
Export many things
Wrap them in an object.
module.exports = { x, calculateSum }exports both at once.- Import with destructuring:
const { x, calculateSum } = require("./sum"). - Alternative: attach properties one at a time —
module.exports.x = x. - Destructuring is the professional default — expect it in every production codebase.
Folders + index.js (barrel)
Scale up without path spaghetti.
- Put related files in a folder (e.g.
calculate/). - Add
calculate/index.jsthat re-exports siblings. require("./calculate")auto-loadsindex.js— one clean import.- Bonus:
require("./data.json")parses JSON;require("node:util")loads core modules.
CJS vs ESM
Two module systems, one language.
- CJS:
require/module.exports— synchronous, non-strict, Node default. - ESM:
import/export— async, always strict, future standard. - Enable ESM by adding
"type": "module"topackage.json(or use.mjs). - Strict mode gotcha:
z = "hello"works in CJS (sloppy), throws in ESM.
Comments
Comments are disabled in this environment. Set
PUBLIC_GISCUS_REPO,PUBLIC_GISCUS_REPO_ID, andPUBLIC_GISCUS_CATEGORY_IDto enable.