Modules and Import/Export

JavaScript modules help organize code into reusable, maintainable pieces. Understanding module syntax and patterns is essential for modern JavaScript development.

ES6 Modules

// Named exports
export const PI = 3.14159;
export function square(x) {
  return x * x;
}

// Default export
export default class Calculator {
  add(a, b) { return a + b; }
}

// Named imports
import { PI, square } from './math.js';
import { PI as π } from './math.js';

// Default import
import Calculator from './calculator.js';

// Import all as namespace
import * as mathUtils from './math.js';

// Combined imports
import Calculator, { PI, square } from './math.js';

Module Patterns

// Re-exporting
export { default as Calculator } from './calculator.js';
export { PI, square } from './math.js';

// Dynamic imports
async function loadModule() {
  const module = await import('./large-module.js');
  module.doSomething();
}

// Module with side effects
import './styles.css';
import 'bootstrap';

// Barrel exports (index.js)
export * from './math.js';
export * from './calculator.js';
export * from './utils.js';

CommonJS vs ES Modules

// CommonJS (Node.js)
const path = require('path');
module.exports = {
  process() { /* ... */ }
};
exports.helper = function() { /* ... */ };

// ES Modules
import path from 'path';
export function process() { /* ... */ }
export const helper = function() { /* ... */ };

// Converting between formats
// CommonJS
const module = require('./module');
// ES Module equivalent
import module from './module.js';

Advanced Patterns

// Async module pattern
export async function initialize() {
  const config = await loadConfig();
  return {
    start() { /* ... */ },
    stop() { /* ... */ }
  };
}

// Conditional exports
export default process.env.NODE_ENV === 'production'
  ? ProductionAPI
  : DevelopmentAPI;

// Module augmentation
import { original } from './original.js';
export const enhanced = {
  ...original,
  newFeature() { /* ... */ }
};

Common Interview Follow-up Questions

  1. What's the difference between CommonJS and ES modules?
  2. How do circular dependencies work in modules?
  3. When should you use dynamic imports?
  4. How do you handle module loading in different environments?

Best Practices

  • Use named exports for multiple exports
  • Use default exports sparingly
  • Keep modules focused and single-purpose
  • Consider tree-shaking when structuring exports
  • Use barrel files to simplify imports