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

accept require() with non string literal input #113

Closed
wcastand opened this issue May 15, 2020 · 6 comments
Closed

accept require() with non string literal input #113

wcastand opened this issue May 15, 2020 · 6 comments

Comments

@wcastand
Copy link

I'm trying to build an CLI and i request a glob pattern to find all the files and then require them to exec the code.

when i try to build with esbuild, i get this error :
The argument to require() must be a string literal

From other issues, I've seen that you want to analyze the dependencies and that's why esbuild requires string literal.

but in my case i need to require dynamically, is there a way to do this or esbuild won't work for CLI that use require to load files based on a pattern?

this is currently what i do:

;(async () => {
  await new Promise((r) => {
    glob(
      resolve(cli.input[0] || './*.test.?(tsx|ts)'),
      {},
      async (err, files) => {
        if (err) throw err
        if (files.length === 0) console.log(`No files found.`)
        await Promise.all(
          files.map(async (f) => {
            const outfile = `.ttaped/${relative('.', f.replace('.ts', '.js'))}`
            const options: BuildOptions = {
              stdio: 'inherit',
              entryPoints: [f],
              outfile,
              minify: true,
              platform: 'node',
              bundle: true,
            }

            await build(options)
              .then(() => require(resolve(outfile)))
              .catch(() => process.exit(1))
          }),
        )
        fs.rmdirSync(resolve('.ttaped'), { recursive: true })
        r(true)
      },
    )
  })
})
@evanw
Copy link
Owner

evanw commented May 21, 2020

Thanks for this issue. I agree that this is a good escape hatch to have, and that it would let more real-world code be bundled with esbuild. That code may crash at run time if the files aren't there or if the bundle is used in the browser, but at least the bundling process would succeed. This could be useful in cases like this or in cases where the crash may not matter (e.g. it's in code that is never called).

I'm not quite sure what the best way of adding this is yet. Rollup just passes this straight through without a warning, which seems somewhat dangerous. But it might be the simplest way to solve this. I'll have to think more about this.

@wcastand
Copy link
Author

thank for taking the time to answer, let me know if I can help in any way :)

@kritzware
Copy link

This is the only issue preventing esbuild from being able to build our medium-large production codebase, due to a couple of dependencies using require in this way (which is out of our control).

I would also be happy to help on this if needed 👍

@evanw evanw closed this as completed in 792652c Jun 12, 2020
@evanw
Copy link
Owner

evanw commented Jun 12, 2020

As of version 0.5.3, using require() with non string literal input is now a warning instead of an error. Hopefully this unblocks some use cases for esbuild that were previously blocked.

@jawadwaseem-10p
Copy link

Has there been any workaround proposed for this?

@zaydek
Copy link

zaydek commented Jan 16, 2021

Nevermind, still figuring this out.

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

5 participants