typescriptbeginner
ESM and CJS Module Interop
Handle ECMAScript module and CommonJS interop with dynamic imports, conditional exports, and dual packages.
typescriptPress ⌘/Ctrl + Shift + C to copy
// === ESM Module (math.mts) ===
// Named exports
export function add(a: number, b: number): number {
return a + b;
}
export function multiply(a: number, b: number): number {
return a * b;
}
// Default export
export default { version: '1.0.0' };
// === Importing CJS from ESM ===
// Dynamic import (works in both ESM and CJS)
async function loadCjsModule() {
// import() works for CJS modules in ESM context
const fs = await import('fs');
const path = await import('path');
console.log(path.resolve('.'));
}
// === CJS consuming ESM (must use dynamic import) ===
// In a .cjs file:
// async function main() {
// const { add, multiply } = await import('./math.mjs');
// console.log(add(2, 3));
// }
// === Dual Package pattern (package.json) ===
const dualPackageJson = {
name: 'my-lib',
type: 'module',
main: './dist/cjs/index.cjs', // CJS entry
module: './dist/esm/index.js', // ESM entry
types: './dist/types/index.d.ts',
exports: {
'.': {
import: {
types: './dist/types/index.d.ts',
default: './dist/esm/index.js',
},
require: {
types: './dist/types/index.d.cts',
default: './dist/cjs/index.cjs',
},
},
'./utils': {
import: './dist/esm/utils.js',
require: './dist/cjs/utils.cjs',
},
},
};
// === __dirname / __filename in ESM ===
import { fileURLToPath } from 'url';
import { dirname } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
console.log('Current file:', __filename);
console.log('Current dir:', __dirname);
// === Detect module system ===
function isESM(): boolean {
return typeof import.meta !== 'undefined';
}
export { dualPackageJson, loadCjsModule };Use Cases
- Library dual packaging
- Migration from CJS to ESM
- Cross-module-system compatibility
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptadvanced
Node.js Worker Threads for Parallel Processing
Use Worker Threads to run CPU-intensive tasks in parallel without blocking the event loop.
Best for: CPU-intensive data processing without blocking
#nodejs#worker-threads
typescriptintermediate
Node.js Stream Pipeline with Transform
Build efficient data processing pipelines using Node.js streams for large file handling.
Best for: Processing large CSV files without loading into memory
#nodejs#streams
typescriptintermediate
TypeScript Typed Event Emitter
Create type-safe event emitters in Node.js with full TypeScript support and autocomplete.
Best for: Type-safe pub/sub communication between modules
#nodejs#events
typescriptintermediate
Node.js Graceful Shutdown Handler
Implement graceful shutdown to properly close connections and finish requests before exit.
Best for: Production Node.js server reliability
#nodejs#shutdown