mcrumm

mcrumm

Phoenix Core Team

DartSass - An installer for sass

If you would like to migrate away from node/npm/webpack while still using sass, the dart_sass package provides a installer and runner for Dart Sass via Mix.

This package follows the same structure esbuild– you add your configuration to config.exs:

config :dart_sass,
  version: "1.36.0",
  default: [
    args: ~w(css/app.scss ../priv/static/assets/app.css),
    cd: Path.expand("../assets", __DIR__)
  ]

and then you can run it from your command line:

$ mix sass default --version
1.36.0

For any Phoenix projects currently using Sass via webpack, you can use dart_sass to model your asset pipeline in the upcoming style of the Phoenix v1.6 installer.

First, add DartSass as a watcher in config/dev.exs:

sass: {
    DartSass,
    :install_and_run,
    [:default, ~w(--embed-source-map --source-map-urls=absolute --watch)]
  }

Note: this requires Phoenix > v1.5.9.

…and then create or add sass to your "assets.deploy" alias in mix.exs:

"assets.deploy": ["sass default --no-source-map --style=compressed", "phx.digest"]

You may refer to the README for more details, and if you are using dart_sass in a project, please let us know!

Most Liked

chrismccord

chrismccord

Creator of Phoenix

Gotcha. Agree this would be amazing since I really love tailwind (which heavily builds on postcss), but the long term repeatability of my css builds years down the road is a concern without such a thing.

tj0

tj0

This looks awesome. I can’t wait to not have to install node or npm ever again.

chrismccord

chrismccord

Creator of Phoenix

The goal is to sidestep the node ecosystem and related baggage/reproducible builds by installing the precompiled binaries for DartSass in this case. If postcss could provide something similar that would be amazing, but afaik this is not something easily done given postcss’s node implementation.

mcrumm

mcrumm

Phoenix Core Team

I just published v0.2.0:

  • No longer load config/runtime.exs by default, instead support --runtime-config flag
  • Update initial sass version to 1.39.0
  • mix sass.install --if-missing also checks version
mikeclark

mikeclark

First, this DartSass installer is awesome. Thank you, @mcrumm!

In terms of using standalone Tailwind and DartSass together, here’s something I’ve been experimenting with that might help…

In educational apps specifically, I often want to avoid using a lot of Tailwind utility classes in templates. To do that, I rely on Tailwind’s @apply directive. And when it’s a fairly significant amount of CSS, it’s often handy to use CSS nesting which is where DartSass comes in.

Here’s an example css/app.scss file that demonstrates the problem in an abbreviated form:

@tailwind base;
@tailwind components;
@tailwind utilities;

.card {
  @apply p-4 bg-blue-300 text-blue-800 rounded-lg;

  & .title {
    @apply text-2xl tracking-tight font-bold;
  }

  & .details {
    @apply pt-4 text-lg font-medium;

    & a {
      @apply underline;
    }
  }
}

Now if you run that file through the Tailwind CLI alone, it won’t flatten out the nesting. (The @tailwind/nesting package isn’t baked into the Tailwind CLI as far as I can tell).

However, you can first run that file through DartSass and then run the result through the Tailwind CLI. In other words, pipe the output of one into the other.

Here’s how I’ve been doing it:

First, setup the watchers in the right order:

  watchers: [
    dartsass: {DartSass, :install_and_run, [:default, ~w(--watch)]},
    tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}
  ]

Then configure dart_sass to process app.scss and drop the result in an intermediate file named app.tailwind.css for example:

config :dart_sass,
  version: "1.49.0",
  default: [
    args: ~w(css/app.scss ../priv/static/assets/app.tailwind.css),
    cd: Path.expand("../assets", __DIR__)
  ]

Finally, configure tailwind to use the DartSass output file as its input and spit out the final output in app.css:

config :tailwind,
  version: "3.0.18",
  default: [
    args: ~w(
      --config=tailwind.config.js
      --input=../priv/static/assets/app.tailwind.css
      --output=../priv/static/assets/app.css
    ),
    cd: Path.expand("../assets", __DIR__)
  ]

I’ve only been experimenting with this for a couple days, so there are likely limitations I haven’t bumped into yet.

Is that the sort of thing you’re trying to do, @hxgdzyuyi?

I look forward to hearing of better ways to do this. :wink:

Where Next?

Popular in Libraries Top

blatyo
https://www.conduitframework.com/ The best overview for how things are tied together is this presentation. Modules and functions are pre...
New
dbern
I’m excited to announce that TaxJar has developed and open-sourced DateTimeParser. We developed it because we found a need to parse user ...
New
mcrumm
If you would like to migrate away from node/npm/webpack while still using sass, the dart_sass package provides a installer and runner for...
New
praveenperera
FastRSS Parse RSS feeds very quickly: This is rust NIF built using rustler Uses the RSS rust crate to do the actual RSS parsing Speed...
New
sabiwara
Dune is a sandbox for Elixir and aims to safely evaluate user-provided code. You can try it out using this basic Elixir playground made ...
New
danschultzer
In short Plug n’ play OAuth 2.0 provider library. Just set up a resource owner schema with Ecto (your user schema), install the dependen...
New
bryanjos
Hi, I just published version 0.23.0 of Elixirscript. Most of the changes are around JavaScript interop now that Elixirscript uses the ...
New
handnot2
Samly can be used to enable SAML 2.0 Single Sign On in a Plug/Phoenix application. This library uses Erlang esaml to provide plug enabl...
New
KallDrexx
For a good number of months I've been working on creating a very basic RTMP live video streaming server. Now that I have a very, very ba...
New
ostinelli
Let’s write a database! Well not really, but I think it’s a little sad that there doesn’t seem to be a simple in-memory distributed KV da...
New

Other popular topics Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New

Sub Categories:

We're in Beta

About us Mission Statement