For a recent project, I needed to use the popular Bootstrap theme, using the Sass starterkit for easy CSS management.
The project is hosted on Acquia Cloud, and the quickest way to start a new Drupal project that deploys to Acquia Cloud is to use BLT (a tool for Building, Testing, and Launching Drupal sites). BLT is an automation framework for running and building Drupal sites locally (it even integrates with Drupal VM!), and it is able to test, build, and deploy code on Acquia Cloud.
One aspect of modern theme development that's important to add to your build process is compilation and optimization of your theme's assets—especially CSS! Many modern sites build their themes using Less or Sass, and this introduces a step where you need to compile your styles into one or more stylesheets.
During development, it's nice to have stylesheets that are verbose and easy to read. But when you deploy, it's best to have a minified/optimized CSS file for better front-end performance.
Here's how I set up a custom Bootstrap theme with BLT so I could develop the theme locally and have it compiled and optimized for my production website on Acquia Cloud.
Creating a Bootstrap Sass starterkit subtheme
The first step was to add Bootstrap to the BLT project. Since BLT projects use Composer, I can composer require
the right version, and Composer and BLT takes care of installing the theme:
$ composer require drupal/bootstrap ^8.3.1
After a few minutes, the Bootstrap theme should be part of your project's codebase. Next up, you need to create your own subtheme based on one of the Bootstrap starterkits (now located in docroot/themes/contrib/bootstrap/starterkits
). Copy the sass
folder out to your new theme folder—in my case, docroot/themes/custom/myproject_theme
.
Follow the Bootstrap Sub-Theming instructions to rename everything correctly. When you commit this custom theme to your repository, if BLT complains about a syntax error in the .theme
file, make sure you add a space after the opening PHP tag (I opened an issue to get this fixed, hopefully my patch is merged soon!).
Configure your theme to compile Sass using Node and Gulp
One thing that's lacking in the Bootstrap starterkit is any kind of automated Sass compilation tooling. You're basically told to 'use your own Sass setup' to compile the CSS.
Because of this, we need to add a little configuration to our theme to make sure it's easy to:
- Watch the Sass files for changes and compile CSS on-the-fly during development.
- Compile and optimize CSS for deployment.
- Run other front-end build steps, like image optimization, linting, etc.
I look to Acquia's new Cog theme for front end inspiration, since it puts together a set of build tools and foundational theme components in a cohesive starter package (much like Zen, another theme I use often). Cog includes a Node and Gulp-based workflow for building assets, and allows developers with Node/Gulp installed to run gulp
to build front end assets, or gulp watch
to watch for file changes and build on-the-fly (just like compass
in the Ruby world).
From Cog's repository, I copied over the gulp-tasks
directory, the gulpfile.js
file, and the package.json
file. These three files contain the bulk of the setup required to automatically run gulp
tasks for a Bootstrap theme.
From that point, it was a matter of removing the bits that I didn't need (e.g. KSS-Node integration, JS linting, etc.). I can add them in later if necessary, but this particular project doesn't require them.
In the end, my gulp-tasks
included just the following:
build.js
clean.js
compile-sass.js
default.js
minify-css.js
watch.js
I adjusted the code inside those tasks to match the changed/simpler set of tasks, and made sure the scripts
inside package.json
which are run with npm [script-key]
were correct.
At this point, if I manually run npm install
in the theme's directory, then gulp
(or npm build
, which is basically an alias to gulp
), then the Sass is compiled and it's time to start theming!
Configure BLT to perform Sass compilation
Now that you know how to compile Sass to CSS on your own, you need to tell BLT how to work with the frontend build pipeline.
BLT builds in support for the most common steps. In blt/project.yml
file, you can set a command to run to set up/install the Front End tools (e.g. npm install
, or something similar, to install or update all dependencies), as well as a folder in which to run the command.
There's also a configurable build hook to actually compile your theme's CSS. For my project, I set up all the build tools using npm
, and then I use gulp
to run the compilation and linting tasks, so I have my Front End target-hooks
set up like this (inside my project.yml
):
target-hooks:
frontend-setup:
dir: '${docroot}/themes/custom/myproject_theme'
command: 'npm install && npm install -g gulp'
frontend-build:
dir: '${docroot}/themes/custom/myproject_theme'
command: 'gulp'
...
Now, whenever a developer initializes the project on a local machine, these two commands will be run automatically. They'll also be run any time the local environment is reinstalled or refreshed from another environment.
All you need to do is make sure the developer has Node.js/npm
installed (on a Mac, I use brew install nvm
to install the Node Version Manager), then I use nvm
to install
and use
a specific version of Node.js. Once that's done, BLT takes care of the rest.
Don't commit development CSS files to the repository
One of the easiest ways to make developers go insane is to commit compiled CSS files to the repository. CSS changes will sneak into almost every pull request, because one developer has one version of Node, another developer has a debugging setting enabled, etc.
Instead of committing the compiled CSS, you should add the following to the .gitignore
file in your project root (I added it under the 'Sass' section):
docroot/themes/custom/myproject_theme/css/*
There's a problem, though: since the css
directory is in the project's gitignore, BLT won't include compiled CSS when it's deploying builds. Luckily, there's a solution: you can provide BLT with a separate .gitignore file to be used when building deployment artifacts!
Add the following to your blt/project.yml
file:
deploy:
gitignore_file: ${repo.root}/blt/files/.gitignore
Then create a deployment-artifact-specific gitignore file (without the css
directory exclusion) in blt/files/.gitignore
. You can use the .gitignore
file in the repository root as a template.
Compile CSS for production deployment artifacts
Since you're using BLT's target-hooks
for compilation, there's really nothing else you need to do at this point. When BLT builds your project—either using Travis CI, Jenkins, Acquia Pipelines, or some other CI tool—it will automatically run the commands to build your front-end assets every deploy.
As long as your theme is configured to use the CSS stylesheet(s) in the theme's css
directory, everything should work on all your Acquia Cloud environments, and your site's Bootstrap-based theme will look great!