esbuild icon indicating copy to clipboard operation
esbuild copied to clipboard

Cannot define template string

Open hesxenon opened this issue 10 months ago • 4 comments

It seems there is currently no way to define template strings.

https://esbuild.github.io/try/#dAAwLjI1LjAALS1kZWZpbmU6Rk9PPSdgZm9vYCcA

I would like this option to inject HTML templates into a bundle at build time (don't ask why, constraints and such...).

My current workaround is to join all lines in the template and sanitize the string so that special chars are escaped. Works, but is a bit more tedious than simply passing a template literal.

hesxenon avatar Feb 26 '25 10:02 hesxenon

For complex variable replacing cases, a common solution in esbuild is using the inject option to provide the implementation in a real js file, example.

hyrious avatar Feb 26 '25 15:02 hyrious

Yes, inject is a good solution. Another way this is typically done is to use esbuild's JS API instead and use JSON.stringify() to create a string.

Can you provide an example of what you're actually trying to do? What code are you using to generate this now, and what would you like it to look like instead? I'm asking because trying to pass template strings on the command line without escaping their contents sounds like a bad idea to me. For example, if your template string was `foo's` instead, then your shell could potentially emit a syntax error due to the mismatched single quotes.

Given that, I don't think it makes sense to support this workflow. If you're running into issues passing complicated data that potentially needs to be escaped on the command line, then IMO the best approach is to avoid using the CLI. That also avoids portability issues around different shells having different escape character behavior.

evanw avatar Mar 09 '25 19:03 evanw

I am not actually using the CLI but thought it appropriate for a demo, I apologize for the confusion.

Inject is probably the way to go, yes.

Just for the record, a pseudo example:

<!-- foo.html -->
<html lang="en">
  <head>
    <script src="https://unpkg.com/[email protected]"></script>
    <script src="https://unpkg.com/[email protected]"></script>
    <meta name="htmx-config" content='{"selfRequestsOnly":false}' />
  </head>
  <body>
    <main
      _='
      on htmx:configRequest 
        set event.detail.path to `http://localhost:10000/sandbox${event.detail.path}`
        log event.detail
      '
    >
      <div hx-trigger="load" hx-get="/">Loading...</div>
    </main>
  </body>
</html>
const foo = Fs.readFileSync("foo.html", "utf8");

await Esbuild.build({
  define: {
    FOO: `${foo}`
  }
});

So you can see the HTML is not exactly "trivial" from this perspective, since it includes JSON values and template strings as well.

hesxenon avatar Mar 10 '25 08:03 hesxenon

Unless I'm misunderstanding something, the way to do this right now would be to use JSON.stringify() to turn the string foo into JS source code suitable for use with define:

 const foo = Fs.readFileSync("foo.html", "utf8");

 await Esbuild.build({
   define: {
-    FOO: `${foo}`
+    FOO: JSON.stringify(foo)
   }
 });

evanw avatar Mar 10 '25 19:03 evanw