DEV Community

Masatoshi Nishiguchi
Masatoshi Nishiguchi

Posted on • Edited on

4 1

Elixir Phoenix 1.6 Esbuild + SCSS

I want to leave a note about what I stumbled on in my setting up SCSS for my Phoenix 1.6 app.
I need SCSS because I enjoy customizing Bootstrap styles using SCSS. I am not planning to use Tailwind.

にほんご

TL;DR

phoenixframework/esbuild

  • preconfigured in a newly-generated Phoenix 1.6 app
  • bundles JS files into priv/static/assets/assets/app.js
  • bundles CSS files into priv/static/assets/assets/app.css in case CSS files are imported into some JS files
  • the esbuild executable gets installed automatically as long as phoenixframework/esbuild is configured correctly
  • for SCSS we need use either:
  • typically in development, we use Phoenix.Endpoint watcher so esbuild can build assets every time we make changes in our assets
  • typically in production, we compile assets

configure esbuild

Three files are involved for configuring phoenixframework/esbuild.

  • mix.exs
    • elixir-related settings
  • config/config.exs
    • esbuild-related settings
    • we need to specify as args:
    • the version of the esbuild executable we want to use
    • input file
    • output dir
    • etc
  • config/dev.exs

It is a lot easier than I expected. But by default esbuild does not know how to handle SCSS files. CargoSense/dart_sass comes in handy when we really want to use SCSS.

CargoSense/dart_sass

configure esbuild

Just like phoenixframework/esbuild, three files are involved for configuring CargoSense/dart_sass.

  • mix.exs
  • config/config.exs
  • config/dev.exs

Initially I just copied and pasted all the snippets from the ducumentation thoughtlessly and one issue occurred. Because when both phoenixframework/esbuild and CargoSense/dart_sass are used and they both output the CSS build results to the same file priv/static/assets/app.css, which means they keep on overriding that same file.

After all, I realized the following:

  • the easiest way is to use phoenixframework/esbuild for JS only and use CargoSense/dart_sass for SCSS
  • it is nice to give the destination file a name other than assets/app.css for debuggability later on (E.g., "assets/from_scss.css")

Then our HTML template reference those files separately.

<!-- lib/my_app_web/templates/layout/root.html.heex -->

-  <link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/app.css")}/>
+  <link phx-track-static rel="stylesheet" href={Routes.static_path(@conn, "/assets/from_scss.css")}/>
   <script defer phx-track-static type="text/javascript" src={Routes.static_path(@conn, "/assets/app.js")}></script>
Enter fullscreen mode Exit fullscreen mode

My config/config.exs ended up looking like this.

# config/config.exs

...

# Configure esbuild (the version is required)
config :esbuild,
  version: "0.14.1",
  default: [
    args: [
      "js/app.js",
      "--bundle",
      "--target=es2016",
      "--outdir=../priv/static/assets",
      "--external:/fonts/*",
      "--external:/images/*"
    ],
    cd: Path.expand("../assets", __DIR__),
    env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
  ]

# https://github.com/CargoSense/dart_sass
config :dart_sass,
  version: "1.44.0",
  default: [
    args: [
      "scss/index.scss",
      "../priv/static/assets/from_scss.css"
    ],
    cd: Path.expand("../assets", __DIR__)
  ]
...
Enter fullscreen mode Exit fullscreen mode

phoenixdiff.org

If we want to migrate an app from Phoenix 1.5 to Phoenix 1.6, phoenixdiff.org is a nice tool. It reveals all the changes between different versions.

🎉🎉🎉

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs