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
- All explained in Phoenix 1.6 Asset Management documentation.
- The easiest way is to use phoenixframework/esbuild for JS only and use CargoSense/dart_sass for SCSS.
- We need to think through how we want to build our assets beforehand rather than just copy and paste snippets.
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:
- CargoSense/dart_sass
- esbuild plugins
- 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
- Phoenix.Endpoint watcher specific settings for development
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
- similar to phoenixframework/esbuild, but designed specially for SCSS
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>
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__)
]
...
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.
🎉🎉🎉
Top comments (0)