Esbuild: accept require() with non string literal input

Created on 15 May 2020  路  4Comments  路  Source: evanw/esbuild

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)
      },
    )
  })
})

Most helpful comment

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.

All 4 comments

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.

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

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 馃憤

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mixtur picture mixtur  路  4Comments

elektronik2k5 picture elektronik2k5  路  3Comments

vforsh picture vforsh  路  3Comments

a7ul picture a7ul  路  3Comments

ojanvafai picture ojanvafai  路  3Comments