Modules, Imports, Exports, and Modern JavaScript
Understand ES modules, CommonJS, module boundaries, live bindings, dynamic imports, and modern language features used in production applications.
ES Modules
ES modules provide a standardized module system using import and export. Modules have their own top-level scope, execute in strict mode, and can expose selected bindings.
Named exports and default exports have different semantics. Named exports are often preferable when a module exposes several independent concepts because import names can communicate intent.
export function add(a, b) {
return a + b;
}
export const version = '1.0.0';
// another file
import { add, version } from './math.js';- ES modules create their own scope.
- Modules execute in strict mode.
- Named exports communicate specific module capabilities.
What keyword is used to expose a binding from an ES module?
Live Bindings
ES module imports are live bindings rather than copied snapshots. An imported binding reflects changes made to the exported binding by the exporting module. However, the importing module cannot directly reassign the imported binding.
This behavior is important for understanding shared module state and circular dependencies.
// counter.js
export let count = 0;
export function increment() {
count++;
}
// app.js
import { count, increment } from './counter.js';
console.log(count);
increment();
console.log(count);- ES module imports are live bindings.
- Imported bindings cannot be reassigned by the importer.
- Live bindings influence circular dependency behavior.
Are ES module imports simple copied values?
Dynamic import()
Dynamic import() loads a module asynchronously and returns a Promise for its module namespace object. It is useful for lazy loading, conditional functionality, and reducing initial application work.
Unlike a static import declaration, dynamic import can be placed inside expressions and functions.
async function openEditor() {
const module = await import('./editor.js');
module.startEditor();
}
openEditor();- dynamic import returns a Promise.
- It enables lazy loading.
- It can reduce initial loading work in large applications.
What does dynamic `import()` return?
CommonJS vs ES Modules
CommonJS uses require() and module.exports, while ES modules use import and export. Node.js supports both systems, but they have different loading and interoperability semantics.
ES modules are standardized by ECMAScript and support static structure that tooling can analyze. CommonJS is historically important in the Node.js ecosystem and uses a runtime-oriented loading model.
// CommonJS
const path = require('node:path');
module.exports = { path };
// ES Modules
import path from 'node:path';
export { path };- CommonJS and ES modules are distinct module systems.
- ES modules use import/export syntax.
- Node.js supports both with configuration-dependent interoperability.
Which syntax belongs to CommonJS?