phoenixframework / esbuild

An installer for esbuild
MIT License
271 stars 38 forks source link

On install, esbuild deletes line from app.js: import "../css/app.css" #46

Closed CarterQC closed 2 years ago

CarterQC commented 2 years ago

I have css that I want added separately from tailwind, and esbuild pulls it into priv/static/assets the way I need.

I then have the tailwind standalone separately manage tailwind in a separate tailwind.css file, and the html simply links to both.

For some reason though, esbuild seems to be automatically deleting the line import "../css/app.css" from app.js in my assets folder? Is this something that's part of this package, esbuild itself, or is something weird going on?

josevalim commented 2 years ago

It is part of esbuild itself, so you need to check how to customize it there. :)

CarterQC commented 2 years ago

Just a follow up for anyone searching this in the future. I couldn't find docs referring to this in esbuild, so if someone has a link please do post it, but I was able to solve this by:

  1. creating 2 profiles for esbuild in config.exs. One for css and one for js:

    config :esbuild,
    version: "0.14.0",
    js: [
    args: [
      "js/app.js",
      "--bundle",
      "--target=es2016",
      "--log-level=error",
      "--outdir=../priv/static/assets",
      "--loader:.png=file",
      "--loader:.jpg=file",
      "--loader:.jpeg=file",
      "--loader:.svg=file",
      "--loader:.woff=file",
      "--loader:.woff2=file",
      "--loader:.eot=file",
      "--loader:.ttf=file"
    ],
    cd: Path.expand("../assets", __DIR__),
    env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
    ],
    css: [
    args: [
      "css/app.css",
      "--bundle",
      "--log-level=error",
      "--outdir=../priv/static/assets",
      "--loader:.png=file",
      "--loader:.jpg=file",
      "--loader:.jpeg=file",
      "--loader:.svg=file",
      "--loader:.woff=file",
      "--loader:.woff2=file",
      "--loader:.eot=file",
      "--loader:.ttf=file"
    ],
    cd: Path.expand("../assets", __DIR__),
    env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}

    This has esbuild handle the app.js (no longer contains import ../css/app.css) and then esbuild bundles the app.css in a separate step (which esbuild supports as a first class feature).

  2. Then I added watchers in my dev.exs so that they both run on changes:

    watchers: [
    esbuild: {Esbuild, :install_and_run, [:js, ~w(--sourcemap=inline --watch)]},
    esbuild: {Esbuild, :install_and_run, [:css, ~w(--sourcemap=inline --watch)]},
    tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}
    ]
  3. Added a call to each profile in my mix.exs alias:

    "assets.deploy": [
        "esbuild js --minify",
        "esbuild css --minify",
        "tailwind default --minify",
        "phx.digest"
      ]

For those wondering why there's css and tailwind at the same time, it's because I ran into issues with some css deps that didn't build nicely in other configurations. So instead I:

  1. Process a tailwind.css file (which just contains the @tailwind lines) separately with the standalone tailwind package.
  2. Then I let esbuild handle importing the other app.css file.
    1. That way it builds/outputs the tailwind css to tailwind.css in /priv/static/assets and app.css (any additional css) to the same folder in it's own file.
  3. My root.html just has two links to app.css and tailwind.css instead of one css file bundling them both together.