04-SCSS Preprocessing

So our app is coming along, we have an index page that loads a javascript file and a lovely green background. But css is so old school, we want to be able to write some fancy scss and have a preprocessor convert that to css for us.

For the purposes of this tutorial, I am going to use SCSS, however there are sass, less and other preprocessors available to use in a Broccoli build. Check NPM.

For this, we will use the excellent broccoli-sass-source-maps plugin.

1
2
3
yarn add --dev broccoli-sass-source-maps@^4.0.0 sass@^1.14.0

mv app/styles/app.css app/styles/app.scss

In app/styles/app.scss put:

1
2
3
4
5
$body-color: palegreen;
html {
background: $body-color;
border: 5px solid green;
}

And update your Brocfile.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// Brocfile.js
const funnel = require("broccoli-funnel");
const merge = require("broccoli-merge-trees");
const compileSass = require('broccoli-sass-source-maps')(require('sass'));

const appRoot = "app";

// Copy HTML file from app root to destination
const html = funnel(appRoot, {
files: ["index.html"],
annotation: "Index file",
});

// Copy JS file into assets
const js = funnel(appRoot, {
files: ["app.js"],
destDir: "/assets",
annotation: "JS files",
});

// Compile sass files
const css = compileSass(
[appRoot],
"styles/app.scss",
"assets/app.css",
{
sourceMap: true,
sourceMapContents: true,
annotation: "Sass files"
}
);

// Copy public files into destination
const public = funnel('public', {
annotation: "Public files",
});

module.exports = merge([html, js, css, public], {annotation: "Final output"});

As you can see, we're now using the compileSass plugin to transform our scss file into a css file, and emit it into the /assets directory. The last parameter is an options hash that we will cover in a moment.

Now build & serve and you should see the newly compiled scss file has generated a css file with the addition of the green border on the html element. Pretty neat. You can now use this app/styles/app.scss file as your entrypoint for scss/sass compilation.

Source maps

As the name of the plugin suggests, it supports source maps. Source maps are a great way during development to be able see where styles have come from in the source scss document, rather than the compiled css document.

Try inspecting the html tag right now, you should see the html style is defined in app.css on line 1, however it's actually defined in the app.scss on line 2. This is a fairly trivial example but gets way complicated when you have imported files and lots of scss processing being done.

To enable source maps, add the following to the options hash that's the last parameter to compileSass().

1
2
3
4
5
6
7
8
9
10
11
12
// Brocfile.js
// ...
const css = compileSass(
[appRoot],
"styles/app.scss",
"assets/app.css",
{
annotation: "Sass files",
sourceMap: true,
sourceMapContents: true,
}
);

Now yarn serve and you should see that when inspecting the html tag, the line has changed to line 2 and the file is now app.scss. If you click the file name in the inspector, it should take you to the source app.scss file, showing the original scss, complete with variables.

See the Github repo for more details on further configuration options.

Completed Branch: 04-sass-preprocessing

Next: 05-es6-transpilation