es-module-lexer under the hoodrequire.resolve$ npm i parse-imports
import { parseImports } from 'parse-imports' const code = ` import a from 'b' import * as c from './d' import { e as f, g as h, i } from '/j' import k, { l as m } from 'n' import o, * as p from "./q" import r, { s as t, u } from "/v" import fs from 'fs' ;(async () => { await import("w") await import("x" + "y") })() ` // Lazily iterate over iterable of imports for (const $import of await parseImports(code)) { console.log($import) } // Or get as an array of imports const imports = [...(await parseImports(code))] console.log(imports[0]) //=> // { // startIndex: 3, // endIndex: 20, // isDynamicImport: false, // moduleSpecifier: { // type: 'package', // startIndex: 17, // endIndex: 20, // isConstant: true, // code: `'b'`, // value: 'b', // resolved: undefined // }, // importClause: { // default: 'a', // named: [], // namespace: undefined // } // } console.log(imports[1]) //=> // { // startIndex: 23, // endIndex: 47, // isDynamicImport: false, // moduleSpecifier: { // type: 'relative', // startIndex: 42, // endIndex: 47, // isConstant: true, // code: `'./d'`, // value: './d', // resolved: undefined // }, // importClause: { // default: undefined, // named: [], // namespace: 'c' // } // } console.log(imports[5]) //=> // { // startIndex: 153, // endIndex: 186, // isDynamicImport: false, // moduleSpecifier: { // type: 'absolute', // startIndex: 182, // endIndex: 186, // isConstant: true, // code: '"/v"', // value: '/v', // resolved: undefined // }, // importClause: { // default: 'r', // named: [ // { specifier: 's', binding: 't' }, // { specifier: 'u', binding: 'u' } // ], // namespace: undefined // } // } console.log(imports[7]) //=> // { // startIndex: 238, // endIndex: 249, // isDynamicImport: true, // moduleSpecifier: { // type: 'package', // startIndex: 245, // endIndex: 248, // isConstant: true, // code: '"w"', // value: 'w', // resolved: undefined // }, // importClause: undefined // } console.log(imports[8]) //=> // { // startIndex: 260, // endIndex: 277, // isDynamicImport: true, // moduleSpecifier: { // type: 'unknown', // startIndex: 267, // endIndex: 276, // isConstant: false, // code: '"x" + "y"', // value: undefined, // resolved: undefined // }, // importClause: undefined // }
Use parseImports when you're able to await a Promise result and parseImportsSync otherwise.
[!IMPORTANT]
You can only call
parseImportsSynconce the WASM has loaded. You can be sure this has happened by awaiting the exportedwasmLoadPromise.
See the type definitions for details.
type ModuleSpecifierType = | 'invalid' | 'absolute' | 'relative' | 'builtin' | 'package' | 'unknown' type Import = { startIndex: number endIndex: number isDynamicImport: boolean moduleSpecifier: { type: ModuleSpecifierType startIndex: number endIndex: number isConstant: boolean code: string value?: string resolved?: string } importClause?: { default?: string named: string[] namespace?: string } }
Importcode.substring(startIndex, endIndex) returns the full import statement or expression. code.substring(moduleSpecifier.startIndex, moduleSpecifier.endIndex) returns the module specifier including quotes.
moduleSpecifier.isConstant is true when the import is not a dynamic import (isDynamicImport is false), or when the import is a dynamic import where the specifier is a simple string literal (e.g. import('fs'), import("fs"), import(`fs`)).
If moduleSpecifier.isConstant is false, then moduleSpecifier.type is 'unknown'. Otherwise, it is set according to the following rules:
'invalid' if the module specifier is the empty string'absolute' if the module specifier is an absolute file path'relative' if the module specifier is a relative file path'builtin' if the module specifier is the name of a builtin Node.js package'package' otherwisemoduleSpecifier.code is the module specifier as it was written in the code. For non-constant dynamic imports it could be a complex expression.
moduleSpecifier.value is moduleSpecifier.code without string literal quotes and unescaped if moduleSpecifier.isConstant is true. Otherwise, it is undefined.
moduleSpecifier.resolved is set if the resolveFrom option is set and moduleSpecifier.value is not undefined.
importClause is only undefined if isDynamicImport is true.
importClause.default is the default import identifier or undefined if the import statement does not have a default import.
importClause.named is the array of objects representing the named imports of the import statement. It is empty if the import statement does not have any named imports. Each object in the array has a specifier field set to the imported identifier and a binding field set to the identifier for accessing the imported value. For example, import { a, x as y } from 'something' would have the following array for importClause.named: [{ specifier: 'a', binding: 'a' }, { specifier: 'x', binding: 'y' }].
importClause.namespace is the namespace import identifier or undefined if the import statement does not have a namespace import.
Stars are always welcome!
For bugs and feature requests, please create an issue.