evanw / esbuild

An extremely fast bundler for the web
https://esbuild.github.io/
MIT License
38.08k stars 1.14k forks source link

esbuild creating whitespace around css variables, making them unusable in Chromium #2132

Closed wiktoriavh closed 2 years ago

wiktoriavh commented 2 years ago

I am using esbuild to generate my JS and CSS files. I just started the project, and I can say that it will use a lot of CSS variables, here is an example:

:root .monochrome-spectrum,
.theme-dark.monochrome-spectrum {
  --monochrome-hue: 50;
  --monochrome-saturation: 30;
  --monochrome-lightness: 30;
  /* prettier-ignore */
  --monochrome-hsl: hsl(
    var(--monochrome-hue)deg,
    var(--monochrome-saturation)%,
    var(--monochrome-lightness)%
  );
  --main-node: var(--monochrome-hsl);
}

Note how --monochrome-hsl is build. Variable and then the unit, no spaces. But when I bundle my file, a space was added, making it unusable.

image

The Stylesheet is used in an Electron App (Obsidian).

evanw commented 2 years ago

I can't reproduce this. This is esbuild's output with bundling and without minification:

:root .monochrome-spectrum,
.theme-dark.monochrome-spectrum {
  --monochrome-hue: 50;
  --monochrome-saturation: 30;
  --monochrome-lightness: 30;
  --monochrome-hsl: hsl( var(--monochrome-hue)deg, var(--monochrome-saturation)%, var(--monochrome-lightness)% );
  --main-node: var(--monochrome-hsl);
}

and with bundling and minification:

:root .monochrome-spectrum,.theme-dark.monochrome-spectrum{--monochrome-hue: 50;--monochrome-saturation: 30;--monochrome-lightness: 30;--monochrome-hsl: hsl( var(--monochrome-hue)deg, var(--monochrome-saturation)%, var(--monochrome-lightness)% );--main-node: var(--monochrome-hsl)}

In both cases there is no space inserted in between var() and deg. Can you provide the esbuild configuration that reproduces this issue?

evanw commented 2 years ago

I noticed /* prettier-ignore */ and I thought I'd try this in Prettier. It turns out Prettier messes up this syntax. This is a Prettier bug, not an esbuild bug. Here's Prettier's output on that code:

:root .monochrome-spectrum,
.theme-dark.monochrome-spectrum {
  --monochrome-hue: 50;
  --monochrome-saturation: 30;
  --monochrome-lightness: 30;
  --monochrome-hsl: hsl(
    var(--monochrome-hue) deg,
    var(--monochrome-saturation) %,
    var(--monochrome-lightness) %
  );
  --main-node: var(--monochrome-hsl);
}

I think like this is the Prettier bug you're looking for: https://github.com/prettier/prettier/issues/5407. I'm closing this issue as nothing appears to be wrong with esbuild here.

wiktoriavh commented 2 years ago

@evanw I completly forgot to share my esbuild configuration, here it is.

import dotenv from "dotenv";
import esbuild from "esbuild";
import path from "path";
import process from "process";
import postcss from "esbuild-postcss";

dotenv.config();

const flags = process.argv;

const buildSettings = {
  production: flags.includes("production"),
};

const testingVaultPath = path.join(
  process.env.TESTING_VAULT_PATH,
  ".obsidian",
  "plugins",
  "spectrum-companion"
);

const outSettings = buildSettings.production
  ? { outfile: "main.js" }
  : { outdir: testingVaultPath, outbase: "." };

const entrySettings = {
  main: process.env.ENTRY_FILE,
  styles: "src/styles.css",
};

esbuild
  .build({
    entryPoints: entrySettings,
    bundle: true,
    minify: true, //buildSettings.production,
    external: ["obsidian"],
    // format: "cjs",
    watch: !buildSettings.production,
    target: "es2016",
    logLevel: "info",
    sourcemap: buildSettings.production ? false : "inline",
    treeShaking: true,
    // verbatimWhitespace: true,
    plugins: [postcss()],
    ...outSettings,
  })
  // eslint-disable-next-line unicorn/no-process-exit
  .catch(() => process.exit(1));

The issue being prettier surprises me, as I thought prettier should have nothing to do with the ouput build.

Thanks for looking into it.