Thursday, March 19, 2020

Sitecore SXA CLI how-to: compile and minify CSS at the build server

During the last few weeks I worked a lot with SXA themes and the thing I was concerned about was: storing CSS/JS files in media library / serialization.

Well, there is nothing wrong with media library and it is extremely useful for distributed setups, but pushing compiled (or even minified) files to GIT just to make sure they will be added to the deployment package seemed painfully wrong.

Additionally, it caused merge conflicts when multiple people worked on front-end part of the site.

Luckily, it is not complicated at all to change that while maintaining typical delivery workflow. What we need to do is:
  1. Compile / minify .SCSS into .CSS at the build server
  2. Convert compiled file (i.e. *-min.css) into the .yml
  3. Package .yml into update package (trivial with Sitecore Courier)

Compile / minify .SCSS into .CSS at the build server
This part actually requires some customization as there is no built-in "minify CSS" task exposed. What we need to do is add custom gulp task called "sassMinify":

const gulp = require("gulp");
const cssMinificator = require('@sxa/celt/util/cssMinificator');
gulp.task('sassMinify', function() {

and call it along with other tasks in a "build" command

    "build": "gulp sassComponents && gulp sassStyles && gulp sassMinify"

After you run "npm run build" locally or at the build server, stylesheets will be compiled and minified. 

Convert compiled file (i.e. *-min.css) to .yml
For this part I decided to use PowerShell and ended up with a quite short script:

function Update-ThemeTokens($filePath, $itemPath)
    $blob = [Convert]::ToBase64String([IO.File]::ReadAllBytes($filePath))
    $size = (Get-Item $filePath).length
    $content = Get-Content -Path $itemPath
    $content = $content -replace '%blob%', $blob
    $content = $content -replace '%size%', $size
    $itemPath = $itemPath -replace '.template', ''
    $content | Set-Content -Path $itemPath

$demoCss = Join-Path $PSScriptRoot "styles\pre-optimized-min.css"
$demoItem = Join-Path $PSScriptRoot "items\demo\styles\pre-optimized-min.yml.template"

Update-ThemeTokens $demoCss $demoItem

Obviously, you'd need to create pre-optimized-min.yml.template with %blob% and %size% tokens (by copying existing pre-optimized-min.yml file and replacing the blob and the size values). Here's the example:

No comments:

Post a Comment