framework icon indicating copy to clipboard operation
framework copied to clipboard

esbuild crashes when style.css contains @font-face definitions

Open Fil opened this issue 1 year ago • 3 comments

following https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face I create a style.css file with:

@font-face {
  font-family: "Trickster";
  src:
    local("Trickster"),
    url("trickster-COLRv1.otf") format("opentype") tech(color-COLRv1),
    url("trickster-outline.otf") format("opentype"),
    url("trickster-outline.woff") format("woff");
}

the css bundling crashes with recommendations to "mark paths as external" (unhelpful, since this is commandeered by framework, not by the user), reference:

style docs/style.css → ✘ [ERROR] Could not resolve "trickster-COLRv1.otf"

    docs/style.css:5:8:
      5 │     url("trickster-COLRv1.otf") format("opentype") tech(color-COLRv1),
        ╵         ~~~~~~~~~~~~~~~~~~~~~~

  You can mark the path "trickster-COLRv1.otf" as external to exclude it from
  the bundle, which will remove this error and leave the unresolved path in the
  bundle.

✘ [ERROR] Could not resolve "trickster-outline.otf"

    docs/style.css:6:8:
      6 │     url("trickster-outline.otf") format("opentype"),
        ╵         ~~~~~~~~~~~~~~~~~~~~~~~

  You can mark the path "trickster-outline.otf" as external to exclude it from
  the bundle, which will remove this error and leave the unresolved path in the
  bundle.

✘ [ERROR] Could not resolve "trickster-outline.woff"

    docs/style.css:7:8:
      7 │     url("trickster-outline.woff") format("woff");
        ╵         ~~~~~~~~~~~~~~~~~~~~~~~~

  You can mark the path "trickster-outline.woff" as external to exclude it from
  the bundle, which will remove this error and leave the unresolved path in the
  bundle.


Unexpected error: Build failed with 3 errors:
docs/style.css:5:8: ERROR: Could not resolve "trickster-COLRv1.otf"
docs/style.css:6:8: ERROR: Could not resolve "trickster-outline.otf"
docs/style.css:7:8: ERROR: Could not resolve "trickster-outline.woff"

Fil avatar Feb 14 '24 10:02 Fil

Here's a way to fix this:

--- a/src/rollup.ts
+++ b/src/rollup.ts
@@ -25,6 +25,7 @@ function rewriteInputsNamespace(code: string) {
 export async function bundleStyles({path, theme}: {path?: string; theme?: string[]}): Promise<string> {
   const result = await build({
     bundle: true,
+    loader: {".svg": "dataurl", ".eot": "dataurl", ".otf": "dataurl", ".woff": "dataurl"},
     ...(path ? {entryPoints: [path]} : {stdin: {contents: renderTheme(theme!), loader: "css"}}),
     write: false,
     alias: STYLE_MODULES

I don't know enough yet about esbuild: do we really have to explicitly list all the resource types that we may want to inline as css data-urls? If so, which ones should we include? (above, I've included 3 typical font formats + svg; this probably needs more image formats (at least png?), woff2, ttf…).

Another method would be to add these references to _import/ but it seems like a tall order.

Fil avatar Feb 14 '24 10:02 Fil

~~While I'm in this section… shouldn't we minify on build?~~ → this point is discussed in #787

Fil avatar Feb 14 '24 11:02 Fil

Ref. esbuild’s on-resolve callback: https://esbuild.github.io/plugins/#on-resolve

mbostock avatar Apr 22 '24 16:04 mbostock