Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return array of modules found in import-statements #100

Closed
MathiasWP opened this issue Jan 7, 2022 · 5 comments
Closed

Return array of modules found in import-statements #100

MathiasWP opened this issue Jan 7, 2022 · 5 comments

Comments

@MathiasWP
Copy link

MathiasWP commented Jan 7, 2022

I am currently using this library in a svelte pre-processor to optimise import-statements, and it is a perfect fit!

It would be awesome to get a list of the modules that are imported in an ImportDeclaration, so that i could skip my "hacky" step of obtaining this information from the current api.

Is this possible to add?

Thanks for reading, your github-profile is a lifesaver to my organization!

@guybedford
Copy link
Owner

It would add a little more overhead to the API, where keeping filesize down is a primary objective of this project as it is used in es-module-shims. If a PR were small enough it might be an option though.

@daKmoR
Copy link
Contributor

daKmoR commented Feb 6, 2022

I just stumbled over this (or a similar) use case as well 😅

I would like to find all import names.

e.g. for this given imports

import { name, foo as bar } from 'mod';
import json from './json.json' assert { type: 'json' }

I would like to get a list of

  • name
  • bar
  • json

@MathiasWP can you share (here a code snippet) your "hacky" version?

@daKmoR
Copy link
Contributor

daKmoR commented Feb 7, 2022

this is my "hacky" version

/**
 * Extracts all import names for an already parsed files
 *
 * @param {import('es-module-lexer').ImportSpecifier} imports
 * @param {string} source
 * @returns {string[]}
 */
export function importsToImportNames(imports, source) {
  const allImportNames = [];
  for (const singleImport of imports) {
    const importStatement = source.substring(singleImport.ss, singleImport.se);
    const importNames = getImportNames(importStatement);
    allImportNames.push(...importNames);
  }
  return allImportNames;
}

/**
 * Extracts all import names from a full import statement
 *
 * import { html, css as litCss } from 'lit';
 * => ['html', 'litCss']
 *
 * @param {string} importStatement
 * @returns {string[]}
 */
export function getImportNames(importStatement) {
  /** @type string[] */
  const importNames = [];

  const singleLine = importStatement.trim().replace(/\n/g, '');
  const fromIndex = singleLine.indexOf('from');
  if (fromIndex >= 0) {
    const importPart = singleLine.substring(6, fromIndex);
    const cleanedImportPart = importPart.replace(/[{}]/g, '');
    const importStatementParts = cleanedImportPart
      .split(',')
      .map(el => el.trim())
      .filter(Boolean);

    for (const importName of importStatementParts) {
      if (importName.includes(' as ')) {
        importNames.push(importName.split(' as ')[1].trim());
      } else {
        importNames.push(importName);
      }
    }
    return importNames;
  }

  return importNames;
}

test example

    it('multiple imports', async () => {
      const source = [
        //
        "import { html, nothing } from 'lit';",
        "import { doIt } from 'nike';",
      ].join('\n');
      const [imports] = parse(source);
      expect(importsToImportNames(imports, source)).to.deep.equal(['html', 'nothing', 'doIt']);
    });

@guybedford
Copy link
Owner

This has now been added in #119.

@MathiasWP
Copy link
Author

I am struggling with figuring out how to get this with the latest release, is it possible to get a small example? 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants