Magento 2 Compile Less With Grunt

Let’s face it, frontend development on Magento 2 is extremely slow! It is a long winded process, each time you make a change to a Less file you have to clear cache and delete the pub/frontend directory to see any visible changes on the frontend. It isn’t a good workflow, it’s not workable.

By using the built in Grunt compilation tool you can help speed things along when building out your themes. It will watch your Less files for changes and compile into CSS. To make things better you can install the LiveReload browser extension and the page will automatically update, no page refresh needed. Compilation time on average takes around 4 seconds which isn’t lightning by any means when compared to todays modern workflows, but it is a lot quicker than not using it.

Today I’m going to show you how to quickly setup the Grunt workflow with only a handful of changes needed.

Before we get started make sure that you set your Magento application to the developer or default mode.

Setup Configuration

First we need to setup the configuration files, there are 3 in total. Rename or duplicate the following files in your Magento root directory:

package.json.sample        to   package.json
grunt-config.json.sample   to   grunt-config.json
Gruntfile.js.sample        to   Gruntfile.js

We don’t need to make any changes to these files, just make sure the grunt-config.js file has the following contents:

{
  "themes": "dev/tools/grunt/configs/local-themes"
}

We’ll be creating this file next which will tell Grunt which themes we want to compile. Create the new file using the JavaScript extension at the path specified in the configuration which should be:

dev/tools/grunt/configs/local-themes.js

Now we need to specify the themes we want Grunt to compile. We can see examples of this in the following file for reference:

dev/tools/grunt/configs/themes.js

It’s best practice not to edit this file, as it is tracked with Git and will get overwritten when upgrading Magento. To avoid this, we are using our own custom configuration file, local-themes.js is also added to your .gitignore by default.

In my instance I’ll add the following contents. Remember to change the name and locale to match up with your settings.

"use strict";

module.exports = {
  jason: {
    area: "frontend",
    name: "Jason/blank",
    locale: "en_GB",
    files: [
      "css/styles-m",
      "css/styles-l"
    ],
    dsl: "less"
  }
};

Install Node.js

Next we need to install Node.js globally on your machine. You may already have this installed, to check if you have run the following command in the terminal:

node -v

If it returns a version you already have it, if not please follow the instructions on their website on how to install.

Once you have Node.js installed within the Magento root directory run the following command in the terminal:

npm install

This will download all the dependencies from your package.json file and put them in a new folder called node_modules.

Install Grunt CLI

Now we need to install the grunt-cli in order to use the Grunt commands later on. Run the following command in the terminal:

npm install -g grunt-cli

This will install it globally on your machine.

Install LiveReload

This step is optional, but highly recommended. This will automatically update the page with the latest CSS changes and no page refresh.

All the modern browsers have an extension you can install, links can be found on their extensions page or search for LiveReload in the browser extensions store.

Run Grunt

The final step is to run the Grunt commands, there are 4 commands available to us which are described in the Magento documentation.

grunt clean   # Removes the theme related static files in the pub/static and var directories.
grunt exec    # Republishes symlinks to the source files to the pub/static/frontend/ directory.
grunt less    # Compiles .css files using the symlinks published in the pub/static/frontend/ directory.
grunt watch   # Tracks the changes in the source files, recompiles .css files, and reloads the page in the browser.

To get things working we need to run the commands in the correct order, grunt exec and grunt less commands must be ran first. If this isn’t done the watch command won’t work. To make things a little more streamlined we can do this in one command. Within the Magento root directory run the following command in the terminal:

grunt exec && grunt less && grunt watch

We can also specify a theme to run the commands against, here we use the name that we specified in the local-themes.js file like so:

grunt exec:jason && grunt less:jason && grunt watch

Now that the grunt watch command is running, if we refresh the browser window and enable the LiveReload extension by clicking the icon to activate it, the page will automatically update when we make changes to the Less files. ???

Gotchas

  • Make sure the locale is setup correctly within your local-themes.js file and matches the locale for your store
  • When adding new Less files you will need to re-run the Grunt commands
  • Useful tip for debugging, if you run grunt watch --verbose it will list the files that are being watched

If you having trouble getting it to work please checkout Magento documentation.