Compile Sass With Eleventy

Instead of using Gulp or Grunt, Eleventy can also compile Sass files directly. The players: the new beforeBuild event and Dart Sass.

Eleventy introduced the event beforeBuild in v0.11.1. This allows to execute user defined javascript before the actual build process starts. The configuration is pretty easy, you just have to add the following line in your eleventy.js configuration file:

eleventyConfig.on("beforeBuild", () => {
    // Custom Code
});

I take advantage of this new event to turn my SCSS into standard CSS before each build. For this I use Dart Sass, for speed reasons with renderSync.

let result = sass.renderSync({
  file: "src/assets/scss/main.scss",
  sourceMap: false,
  outputStyle: "compressed",
});

Dart Sass takes my SCSS source file with it and outputs it in compressed form (without unnecessary whitespace) as a buffer element. Theoretically you could write this buffer element directly as a CSS file.

However, in the second step, I want to run the CSS through PostCSS for further optimization. For this purpose I build a string from the buffer, define the plugins to be used and save the finished file with fs-extra.

let css = result.css.toString();
postcss([postcssPresetEnv, postcssCsso])
  .process(css, { from: "main.css", to: "assets/css/main.css" })
  .then((result) => {
    fs.outputFile("_site/assets/css/main.css", result.css, (err) => {
      if (err) throw err;
      console.log("CSS optimized");
    });
  });

If you put everything together, the final result looks like this:

eleventyConfig.on("beforeBuild", () => {
  // Compile Sass
  let result = sass.renderSync({
    file: "src/assets/scss/main.scss",
    sourceMap: false,
    outputStyle: "compressed",
  });
  console.log("SCSS compiled");

  // Optimize and write file with PostCSS
  let css = result.css.toString();
  postcss([postcssPresetEnv, postcssCsso])
    .process(css, { from: "main.css", to: "assets/css/main.css" })
    .then((result) => {
      fs.outputFile("_site/assets/css/main.css", result.css, (err) => {
        if (err) throw err;
        console.log("CSS optimized");
      });
    });
});