CJS Module Lexer——模具行业从业者必备知识手册
-
<h2>CJS Module Lexer</h2>
<p>[![Build Status][travis-image]][travis-url]</p>
<p>A <a href="#benchmarks">very fast</a> JS CommonJS module syntax lexer used to detect the most likely list of named exports of a CommonJS module.</p>
<p>Outputs the list of named exports (<code>exports.name = ...</code>) and possible module reexports (<code>module.exports = require('...')</code>), including the common transpiler variations of these cases.</p>
<p>Forked from https://github.com/guybedford/es-module-lexer.</p>
<p>Comprehensively handles the JS language grammar while remaining small and fast. - ~90ms per MB of JS cold and ~15ms per MB of JS warm, <a href="#benchmarks">see benchmarks</a> for more info.</p>
<h4>Project Status</h4>
<p>This project is used in Node.js core for detecting the named exports available when importing a CJS module into ESM, and is maintained for this purpose.</p>
<p>PRs will be accepted and upstreamed for parser bugs, performance improvements or new syntax support only.</p>
<p>Detection patterns for this project are <strong>frozen</strong>. This is because adding any new export detection patterns would result in fragmented backwards-compatibility. Specifically, it would be very difficult to figure out why an ES module named export for CommonJS might work in newer Node.js versions but not older versions. This problem would only be discovered downstream of module authors, with the fix for module authors being to then have to understand which patterns in this project provide full backwards-compatibily. Rather, by fully freezing the detected patterns, if it works in any Node.js version it will work in any other. Build tools can also reliably treat the supported syntax for this project as a part of their output target for ensuring syntax support.</p>
<h4>Usage</h4>
<pre><code>
npm install cjs-module-lexer
</code></pre><p>For use in CommonJS:</p>
<pre><code>
const { parse } = require('cjs-module-lexer');//
initreturn a promise for parity with the ESM API, but you do not have to call itconst { exports, reexports } = parse(`
// named exports detection
module.exports.a = 'a';
(function () {
exports.b = 'b';
})();
Object.defineProperty(exports, 'c', { value: 'c' });
/* exports.d = 'not detected'; */// reexports detection
if (maybe) module.exports = require('./dep1.js');
if (another) module.exports = require('./dep2.js');// literal exports assignments
module.exports = { a, b: c, d, 'e': f }// __esModule detection
Object.defineProperty(module.exports, '__esModule', { value: true })
`);// exports === ['a', 'b', 'c', '__esModule']
// reexports === ['./dep1.js', './dep2.js']
</code></pre><p>When using the ESM version, Wasm is supported instead:</p>
<pre><code>
import { parse, init } from 'cjs-module-lexer';
// init() needs to be called and waited upon, or use initSync() to compile
// Wasm blockingly and synchronously.
await init();
const { exports, reexports } = parse(source);
</code></pre><p>The Wasm build is around 1.5x faster and without a cold start.</p>
<h4>Grammar</h4>
<p>CommonJS exports matches are run against the source token stream.</p>
<p>The token grammar is:</p>
<pre><code>
IDENTIFIER: As defined by ECMA-262, without support for identifier\escapes, filtered to remove strict reserved words:
"implements", "interface", "let", "package", "private", "protected", "public", "static", "yield", "enum"STRING_LITERAL: A
"or'bounded ECMA-262 string literal.MODULE_EXPORTS:
module.exportsEXPORTS_IDENTIFIER: MODULE_EXPORTS_IDENTIFIER |
exportsEXPORTS_DOT_ASSIGN: EXPORTS_IDENTIFIER
.IDENTIFIER=EXPORTS_LITERAL_COMPUTED_ASSIGN: EXPORTS_IDENTIFIER `
你们厂里是怎么处理的?来评论区聊聊。
</code></pre>