This RFC is currently in the *Standard* state.

The deadline for this RFC is one week: June 8 2022

*What?*\
This is a proposal to add the [lektor-scss](https://www.getlektor.com/plugins/lektor-scss/) plugin to lego that automatically builds SASS/SCSS files as part of the lektor build process and dev server. The intended outcome will be a lower barrier of entry for contributors, and an easier and less complex build process for each site's SCSS.

*How?*\
The plugin wraps the python libsass library. When the lektor project is built, the plugin calls libsass to compile the source directory to the output directory. Our current SCSS build process of `sass lego/assets/scss:lego/assets/static/css` does the same thing, just with the dart SASS compiler.

When the build server is running, lektor-scss creates a dependency list of SCSS source files, and on rebuilds checks the modification time on source files and only rebuilds when needed.

*Why?*\
Sites using lego (usually) use lego's SCSS bundle. The source for this bundle is in `lego/assets/scss`, and the build bundles are in `lego/assets/static/css`. Sites use these by symlinking the bundle directory, and including the custom-built `bootstrap.css`. When a site wants to update, change, or add to its styles, the SCSS is changed and rebuilt with `sass lego/assets/scss:lego/assets/static/css`. Both of these directories are in lego, which means changing and rebuilding SCSS both require making an MR to lego.

This greatly increases the barrier to entry for contributing. A new contributor (hypothetically) wants to fix a tiny CSS bug on torproject.org. They have to figure out that the CSS is actually stored in lego, clone lego, make their changes, manually install the sass binary and rebuild, then commit to lego, *then* update lego and commit in the tpo repo. With this plugin, the process becomes "clone the tpo repo, make changes to SCSS, and commit"

The plugin also gives us the opportunity to rethink how we use SCSS and lego. If SCSS is built automatically with no dependencies, we won't need to symlink the entire SCSS directory; that lets sites have additional SCSS that doesn't need to be added to lego and doesn't pollute the main bundle used by all the other sites. We also wouldn't need track the built CSS bundles in git; that stops the repo from inflating too much, and reduces noise in commits and merge requests.

*How does this affect lego and existing sites?*\
None of the sites will be affected by this plugin being merged. Each site would have to enable the plugin with a build flag (`-f scss`). Once enabled, the plugin will only update SCSS as needed, using no extra build time unless an SCSS file has changed (which would need to be re-compiled manually anyway).

I ran a few benchmarks; one with the plugin enabled and set to "compact" output, one with the plugin enabled and set to "compressed" output, and one with the plugin installed but disabled. Compressed and disabled were within a second of each other. Compact took an additional 20 seconds, though I'm not sure why.

All of these benchmarks were run in a fresh clone of the tpo repo, with both the repo and lektor build directory in tmpfs. All benchmarks were built twice to deal with translations.

```sh
lektor clean --yes
rm -rf public
find . -type f -iname 'contents+*.lr' -delete
time bash -c 'lektor b -O public &> /dev/null && lektor b -O public &> /dev/null'
```

benchmark results:

enabled, compact:
```
real  6m53.257s
user  6m18.245s
sys   0m31.810s
```

enabled, compressed:
```
real  6m31.341s
user  6m0.905s
sys   0m29.421s
```

disabled:
```
real  6m32.028s
user  6m0.510s
sys   0m29.469s
```

A second run of just compact gave similar results as the others, so I think the first run was a fluke:
```
real	6m30.299s
user	6m0.094s
sys	0m29.328s
```

*What's next?*\
After this plugin is merged, sites that use lego can take advantage of it by creating a `config/scss.ini`, and adding the `-f scss` flag to `lektor b` or `lektor s`. Sites can incorporate it into CI by adding `scss` to the LEKTOR_BUILD_FLAGS CI variable.

```ini
# scss/config.ini
output_dir=assets/static/css
output_style=compact
```

Discussion thread: <https://gitlab.torproject.org/tpo/web/lego/-/issues/27>
