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

Collect data about external modules #905

Closed
eduardoboucas opened this issue Mar 1, 2021 · 1 comment
Closed

Collect data about external modules #905

eduardoboucas opened this issue Mar 1, 2021 · 1 comment
Labels

Comments

@eduardoboucas
Copy link

It would be useful to know which of the modules defined as external were actually required in a build, if any, allowing us to know which modules to package separately.

I've looked at the metafile parameter, but it doesn't seem to contain any information about external modules.

Instead of using external, I could transform the array of module names into a regular expression and use it in a plugin which, for any of those modules, will return external: true and add the module name to an internal structure.

I was trying to avoid the performance penalty of using a plugin, so I was wondering if you'd consider adding this functionality to the core. If so, I'm happy to work on a PR.

Thanks!

@zaydek
Copy link

zaydek commented Mar 13, 2021

I think I understand what you’re trying to do. Instead of looking at package.json and marking all known dependencies as external, something I’ve done previously:

// Dependencies describes dependencies abstractly.
type Dependencies = { [key: string]: string }

// Package describes package.json (only dependencies).
interface Package {
  dependencies: Dependencies
  peerDependencies: Dependencies
  devDependencies: Dependencies
}

async function external(): Promise<string[]> {
  // NOTE: Use try-catch to suppress esbuild dynamic require warning.
  let pkg: Package
  try {
    pkg = require(path.resolve("package.json"))
  } catch {
    return []
  }

  const deps = Object.keys(pkg!.dependencies ?? {})
  const peerDeps = Object.keys(pkg!.peerDependencies ?? {})
  const devDeps = Object.keys(pkg!.devDependencies ?? {})

  // Return distinct dependencies:
  return [...new Set([...deps, ...peerDeps, ...devDeps])]
}

It sounds like you want a more programmatic approach by looking at external: true. Do you think a plugin would cause that much overhead here? If I’m not mistaken, V8 highly optimizes regular expressions, so if they’re compiled in advance (which I think they always are), I can’t imagine this would have a large performance footprint.

Btw it looks like metafile was updated recently: (0.9.2)

  • Remove the metafile from outputFiles (#633)

    Previously using metafile with the API is unnecessarily cumbersome because you have to extract the JSON metadata from the output file yourself instead of it just being provided to you as a return value. This is especially a bummer if you are using write: false because then you need to use a for loop over the output files and do string comparisons with the file paths to try to find the one corresponding to the metafile. Returning the metadata directly is an important UX improvement for the API. It means you can now do this:

const result = await esbuild.build({
  entryPoints: ['entry.js'],
  bundle: true,
  metafile: true,
})
console.log(result.metafile.outputs)

So are you specifically proposing you want / need this API: result.metafile.external?

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

Successfully merging a pull request may close this issue.

3 participants