nodejs / import-in-the-middle

Like `require-in-the-middle`, but for ESM import
https://www.npmjs.com/package/import-in-the-middle
Apache License 2.0
52 stars 20 forks source link

Use `es-module-lexer` to parse ESM #90

Open timfish opened 1 month ago

timfish commented 1 month ago

@AbhiPrasad suggested we use es-module-lexer father than acorn:

A very small single JS file (4KiB gzipped) that includes inlined Web Assembly for very fast source analysis of ECMAScript module syntax only.

For an example of the performance, Angular 1 (720KiB) is fully parsed in 5ms, in comparison to the fastest JS parser, Acorn which takes over 100ms.

Comprehensively handles the JS language grammar while remaining small and fast. - ~10ms per MB of JS cold and ~5ms per MB of JS warm, see benchmarks for more info.

I gave it a test and the entire getEsmExports can be replaced with this:

const { init, parse } = require('es-module-lexer')

async function getEsmExports (moduleSource) {
  await init
  const srcString = moduleSource.toString()
  const [imports, exports] = parse(srcString)

  const reexports = imports
    .map(i => [srcString.slice(i.s, i.e), srcString.slice(i.ss, i.se)])
    .filter(([, full]) => full.match(/export\s*\*\s*from/))
    .map(([file]) => `* from ${file}`)

  const exportNames = exports.map(e => e.n)
  return [...exportNames, ...reexports]
}

A couple of tests fail due to a couple of missing parser features: https://github.com/guybedford/es-module-lexer/issues/175 https://github.com/guybedford/es-module-lexer/issues/176