cjs-module-lexer

raw JSON →
2.2.0 verified Fri May 01 auth: no javascript

A fast CommonJS module syntax lexer that detects named exports and reexports from CJS modules, used in Node.js core for ESM interop. Current stable version: 2.2.0. Maintained by Node.js team; release cadence is irregular but active for parser bugs and performance improvements. Key differentiators: extremely fast (~90ms/MB cold, ~15ms/MB warm), frozen detection patterns to ensure backwards compatibility across Node.js versions, and support for transpiler variations (e.g., TypeScript, Babel). Provides both Node.js (CJS) and Wasm (ESM) builds, with TypeScript declarations included.

error Error: Must call init() before parse()
cause Using ESM import with Wasm build but not calling await init() first.
fix
Add await init(); before any parse() call in ESM context.
error TypeError: parse is not a function
cause Importing cjs-module-lexer incorrectly in CJS, e.g., using default import or wrong destructure.
fix
Use const { parse } = require('cjs-module-lexer'); in CommonJS.
error ReferenceError: exports is not defined
cause Trying to access exports in a context where the CJS wrapper (function(exports, module, require) { ... }) is not provided.
fix
Ensure source code is wrapped in a CommonJS module wrapper when lexing; the lexer expects valid CJS syntax.
error Warning: cjs-module-lexer detected a reexport but the path './foo' is not quoted?
cause Using module.exports = require('./foo') without quotes around the path? Actually, the lexer expects string literals.
fix
Use require('./foo') with a string literal; ensure no dynamic expressions.
breaking In v2.0.0, the Wasm build was introduced and the ESM API changed: init() must be called before parse(). Previously, init() was not required and Wasm was not used.
fix Add await init() before calling parse() in ESM environments. CJS users are unaffected.
deprecated The detection patterns are frozen; new export patterns will not be added. This ensures backwards compatibility but means some modern CJS patterns may not be detected.
fix Do not rely on detection of non-standard patterns. Ensure your code uses the documented export forms (e.g., exports.X = ..., module.exports = { ... }, Object.defineProperty(exports, ...)).
gotcha The lexer does not handle all JavaScript edge cases (e.g., dynamic require, conditional exports inside functions). It uses a token grammar that may miss exports with unusual whitespace or comments.
fix Test your modules with the lexer to ensure expected exports are detected. For complex cases, consider alternative tools.
gotcha The `__esModule` export is always included in the exports array if Object.defineProperty(module.exports, '__esModule', ...) is present. This may be unexpected for some users.
fix Filter out '__esModule' from exports if not needed: exports.filter(e => e !== '__esModule')
breaking Version 1.4.2 included a change that moved to a common wasm-builder, but this was later refined. Users upgrading from 1.x should test exports detection thoroughly.
fix Upgrade to 2.2.0 or later, and verify export detection.
npm install cjs-module-lexer
yarn add cjs-module-lexer
pnpm add cjs-module-lexer

Demonstrates ESM usage with Wasm: import parse and init, await init(), parse a CJS source, and obtain exports/reexports arrays.

import { parse, init } from 'cjs-module-lexer';

const source = `
  module.exports.a = 'a';
  if (maybe) module.exports = require('./dep1.js');
  module.exports = { b, c: d };
`;

await init();
const { exports, reexports } = parse(source);
console.log(exports);   // ['a', 'b', 'c', '__esModule']
console.log(reexports); // ['./dep1.js']