Migrate to Dart Sass from LibSass
What is Dart Sass?
Dart Sass is the primary implementation of Sass, which means it gets new features before any other implementation.
Why migrate from LibSass?
LibSass is now deprecated.
Prerequisites
Applications which use GOV.UK Publishing Components should bundle version 37.1.1 or above.
Installation
- Update your
Gemfile
to replacesassc-rails
withdartsass-rails
and runbundle install
(or with Docker:govuk-docker-run bundle install
)
+ gem "dartsass-rails"
- gem "sassc-rails"
Note, some dependencies of sassc-rails
might be needed in your application. For example, tilt
or sprockets-rails
in which case you should manually add these dependencies to your Gemfile
.
Configuration
Create a builds folder
Create a builds
folder: app/assets/builds
and add a file named .keep
in the corresponding folder.
Ignoring files
Update .gitignore
to ignore all files in the builds
folder , but not .keep
.
+ /app/assets/builds/*
+ !/app/assets/builds/.keep
Update the manifest file
Delete references to your application CSS files from the Sprockets manifest file: app/assets/config/manifest.js
.
- //= link application.css
- //= link components/_component-1.css
- //= link components/_component-2.css
- //= link components/_component-3.css
- //= link components/_component-4.css
- //= link views/_view-1.css
- //= link views/_view-2.css
- //= link views/_view-3.css
- //= link views/_view-4.css
...
Note, do not delete references to vendor CSS files (stylesheets placed in the vendor/assets
folder) to ensure they are processed by Sprockets.
Add a link_tree
directive to link all files in all subdirectories of the builds
folder.
+ //= link_tree ../builds
Add an initializer
If your stylesheets are not individually loaded, or if your application serves only one stylesheet, there’s no need to add a builds
initializer since by default, app/assets/stylesheets/application.scss
will be compiled.
Otherwise, create an initializer: config/initializers/dartsass.rb
. This file will include all Sass entry points and build options.
Rails.application.config.dartsass.builds = {
"application.scss" => "application.css",
"components/_component-1.scss" => "components/_component-1.css",
"components/_component-2.scss" => "components/_component-2.css",
"views/_view-1.scss" => "views/_view-1.css",
"views/_view-2.scss" => "views/_view-2.css",
}
The hash key is the relative path to a Sass file in app/assets/stylesheets/
and the hash value will be the name of the file output to app/assets/builds/
.
Note, if your application uses GOV.UK Publishing Components, and the stylesheets are individually loaded, you will need to merge all entry points, including those from your application and those from GOV.UK Publishing Components.
APP_STYLESHEETS = {
"application.scss" => "application.css",
"components/_component-1.scss" => "components/_component-1.css",
"components/_component-2.scss" => "components/_component-2.css",
"views/_view-1.scss" => "views/_view-1.css",
"views/_view-2.scss" => "views/_view-2.css",
}.freeze
all_stylesheets = APP_STYLESHEETS.merge(GovukPublishingComponents::Config.all_stylesheets)
Rails.application.config.dartsass.builds = all_stylesheets
Also, the initializer should configure build options, incorporating the --quiet-deps
option which tells Sass to suppress dependency deprecation warnings.
Rails.application.config.dartsass.build_options << " --quiet-deps"
Delete unused Sass configuration
Delete Sass configuration previously added for sassc-rails
. Update config/environments/production.rb
to delete
- config.sass.style = :compressed
- config.sass.line_comments = false
...
Builds
dartsass:build
is linked to assets:precompile
. When assets:precompile
is run, it triggers the compilation of Sass files, which are generated in the /app/assets/builds
directory. They are then processed by Sprockets.
Configuring build options
See configuring build options and Dart Sass Command-Line Interface
Watch mode
When you’re developing your application, you can run Sass in watch mode, so stylesheets are continuously updated when Sass files are changed.
- Add
bin/dev
#!/usr/bin/env sh
if ! gem list foreman -i --silent; then
echo "Installing foreman..."
gem install foreman
fi
exec foreman start -f Procfile.dev "$@"
- Add (or update)
procfile.dev
web: bin/rails server -p 3070
css: bin/rails dartsass:watch
Note, the port number should match the one previously specified, in startup.sh
and or docker-compose.yml
, for running your Rails server.
- Update
startup.sh
if [[ $1 == "--live" ]] ; then
GOVUK_APP_DOMAIN=www.gov.uk \
GOVUK_WEBSITE_ROOT=https://www.gov.uk \
GOVUK_PROXY_STATIC_ENABLED=true \
PLEK_SERVICE_CONTENT_STORE_URI=${PLEK_SERVICE_CONTENT_STORE_URI-https://www.gov.uk/api} \
PLEK_SERVICE_STATIC_URI=${PLEK_SERVICE_STATIC_URI-https://assets.publishing.service.gov.uk} \
PLEK_SERVICE_SEARCH_API_URI=${PLEK_SERVICE_SEARCH_API_URI-https://www.gov.uk/api} \
- bundle exec rails s -p 3070
+ ./bin/dev
else
...
- In Docker, update
docker-compose.yml
expose:
- - "3000"
- command: bin/rails s --restart
+ - "3070"
+ command: ./bin/dev
...
Note, you might see a ‘permission denied’ error when executing startup.sh
. If this occurs, you’ll need to modify the permissions for bin/dev
. Navigate to the directory where the bin/dev
script is located. Once you’ve identified the script, use the chmod
command to modify its permissions. For instance, to grant execute permission for the owner, you can use chmod u+x bin/dev
.
Digests
To see the latest stylesheet changes when developing your application, if running Sass in watch mode, you’ll have to turn off digests. Update config/environments/development.rb
to add
config.assets.digest = false
See 3.2 Turning Digests Off - The Asset Pipeline — Ruby on Rails Guides.
Troubleshooting
If you see LoadError: cannot load such file -- sassc
(e.g. when attempting to run tests), try running:
govuk-docker-run rails assets:precompile
If that doesn’t work, read the rails/dartsass-rails troubleshooting guide.
Other issues
Globs
Any form of pattern matching added for importing Sass files will not work. Sass files needs to be imported individually.
- @import "modules/*";
+ @import "modules/module-1";
+ @import "modules/module-2";
+ @import "modules/module-3";
+ @import "modules/module-4";
...
Asset helpers
Asset helpers no longer work in dartsass-rails
. Replace occurrences of the image-url
and asset-url
helpers with the url()
CSS function. See asset_url helpers don’t work - issue #18 - rails/dartsass-rails.
.my-image {
- background-image: image-url("path/to/my/image.svg");
+ background-image: url("path/to/my/image.svg");
background-color: transparent;
...
}
Asset paths
If you are using GOV.UK Frontend in your application you might need to add asset handlers to ensure fonts and images are correctly referenced. See if you have your own folder structure.
@function app-image-url($filename) {
@return url("#{$filename}");
}
$govuk-image-url-function: "app-image-url";