https://github.com/esm-dev/cjs-module-lexer
A lexer for detecting the module.exports of a CJS module.
https://github.com/esm-dev/cjs-module-lexer
Last synced: 12 months ago
JSON representation
A lexer for detecting the module.exports of a CJS module.
- Host: GitHub
- URL: https://github.com/esm-dev/cjs-module-lexer
- Owner: esm-dev
- License: mit
- Created: 2024-06-28T11:27:00.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2025-01-01T05:38:25.000Z (over 1 year ago)
- Last Synced: 2025-04-18T15:17:37.714Z (12 months ago)
- Language: Rust
- Homepage:
- Size: 102 KB
- Stars: 11
- Watchers: 1
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# cjs-module-lexer
A lexer for detecting the `module.exports` of a CJS module, written in Rust.
## Installation
You can install cjs-module-lexer via npm CLI:
```bash
npm i @esm.sh/cjs-module-lexer
```
## Usage
cjs-module-lexer provides a `parse` function that detects the `module.exports` of a commonjs module. The function returns an object with two properties: `exports` and `reexports`. The `exports` property is an array of the exported names, and the `reexports` property is an array of the reexported modules.
```js
import { parse } from "@esm.sh/cjs-module-lexer";
// named exports by assignment
// exports: ["a", "b", "c", "__esModule", "foo"]
const { exports } = parse("index.cjs", `
exports.a = "a";
module.exports.b = "b";
Object.defineProperty(exports, "c", { value: 1 });
Object.defineProperty(module.exports, "__esModule", { value: true })
const key = "foo"
Object.defineProperty(exports, key, { value: "e" });
`);
// reexports
// reexports: ["./lib"]
const { reexports } = parse("index.cjs", `
module.exports = require("./lib");
`);
// object exports(spread syntax supported)
// exports: ["foo", "baz"]
// reexports: ["./lib"]
const { exports, reexports } = parse("index.cjs", `
const foo = "bar"
const obj = { baz: 123 }
module.exports = { foo, ...obj, ...require("./lib") };
`);
// if expression
// exports: ["foo", "cjs"]
const { exports } = parse("index.cjs", `
module.exports.a = "a";
if (true) {
exports.foo = "bar";
}
const mtype = "cjs";
if (mtype === "cjs") {
exports.cjs = true;
} else {
exports.esm = true;
}
if (false) {
exports.unreachable = true;
}
`);
// condition exports by checking if `process.env.NODE_ENV` equals to `nodeEnv` option
// reexports: ["./index.development.js"]
const { reexports } = parse("index.cjs", `
if (process.env.NODE_ENV === "development") {
module.exports = require("./index.development.js")
} else {
module.exports = require("./index.production.js")
}
`, { nodeEnv: "development" });
// block&IIFE
// exports: ["foo", "baz", "__esModule"]
const { exports } = parse("index.cjs", `
{
exports.foo = 'bar'
}
(function () {
exports.baz = 'qux'
if (true) {
return
}
exports.unreachable = true
})();
exports.__esModule = true
`);
// UMD format
// exports: ["foo"]
const { exports } = parse("index.cjs", `
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.MMDParser = global.MMDParser || {})));
}(this, function (exports) {
exports.foo = "bar";
}))
`);
// exports by calling a function
// exports: ["foo"]
const { exports } = parse("index.cjs", `
function module() {
return { foo: "bar" }
}
module.exports = module()
`);
// annotated export names for ESM import
// exports: ["foo", "bar"]
const { exports } = parse("lib.cjs", `
0 && (module.exports = {
foo,
bar,
})
`);
// call reexports
// reexports: ["./lib()"]
const { reexports } = parse("index.cjs", `
module.exports = require("./lib")()
`);
// apply call reexports
// exports: ["foo"]
const { exports } = parse("lib.cjs", `
module.exports = function() {
return { foo: "bar" }
}
`, { callMode: true });
```
The `parse` function has the following types definition:
```ts
export function parse(
specifier: string,
code: string,
options? {
nodeEnv?: 'development' | 'production',
callMode?: boolean,
}
): {
exports: string[],
reexports: string[],
};
```