Skip to content

Understanding JavaScript Module Formats

Qianhe Chen edited this page Nov 9, 2024 · 1 revision

Understanding JavaScript Module Formats

Historical Evolution

1. The Beginning: No Modules

// Old days: Global scope pollution
function helper() { /* ... */ }
var config = { /* ... */ };

// Everything in global scope
window.helper = helper;
window.config = config;

Problems:

  • Global scope pollution
  • Dependencies were hard to manage
  • Loading order matters
  • Naming conflicts

2. CommonJS (CJS) - 2009

Born with Node.js, solving server-side JavaScript needs.

// math.js
module.exports = {
  add: (a, b) => a + b
};

// main.js
const math = require('./math');
console.log(math.add(2, 3)); // 5

Key Points:

  • Synchronous loading
  • Perfect for servers
  • Built for Node.js
  • Not browser-friendly

3. UMD (Universal Module Definition) - 2011

A pattern to support both AMD and CommonJS.

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD
    define(['dependency'], factory);
  } else if (typeof exports === 'object') {
    // CommonJS
    module.exports = factory(require('dependency'));
  } else {
    // Browser globals
    root.myModule = factory(root.dependency);
  }
}(this, function (dependency) {
  return {
    // module implementation
  };
}));

Key Points:

  • Works everywhere
  • Complex syntax
  • Bridge solution
  • Still used for CDN distribution

4. ESM (ECMAScript Modules) - 2015

The official standard for JavaScript modules.

// math.js
export const add = (a, b) => a + b;

// main.js
import { add } from './math.js';
console.log(add(2, 3)); // 5

Key Points:

  • Official standard
  • Static analysis possible
  • Tree-shaking support
  • Browser native support

Why We Need All Three?

Different Environments

1. Node.js        → CommonJS
2. Modern Browser → ESM
3. Old Browser    → UMD

Different Use Cases

1. Build Tools    → ESM (better tree-shaking)
2. Node Scripts   → CommonJS (better tooling)
3. CDN/Direct Use → UMD (no build step)

Common Usage Scenarios

1. Node.js Server

// CommonJS is default in Node.js
const express = require('express');

2. Modern Web App

// ESM in modern development
import React from 'react';

3. Browser Direct

<!-- UMD for direct browser use -->
<script src="https://unpkg.com/library@1.0.0/dist/library.umd.js"></script>

Why Package Authors Provide All Formats

  1. Compatibility

    • Support all environments
    • No user limitations
    • Future-proof
  2. Optimization

    • Better tree-shaking with ESM
    • Direct browser use with UMD
    • Node.js tools with CommonJS

The Future

  • ESM is the future
  • CommonJS still needed for Node.js
  • UMD for legacy support
  • Dual packages common practice

Key Takeaways

  1. Use ESM When:

    • Building modern applications
    • Need tree-shaking
    • Using build tools
  2. Use CommonJS When:

    • Working with Node.js
    • Using older npm packages
    • Need dynamic imports
  3. Use UMD When:

    • Serving via CDN
    • Supporting older browsers
    • Need direct browser usage

Clone this wiki locally