Hello friends! Today, we’ll go over how to use Magento built-in Grunt commands and learn how to add custom configurations to make development faster.
This guide is especially useful if you’re working with a Magento development company, as it can help streamline and speed up your development process.
Overview
You can use Grunt to automate any tasks you need, but out of the box Magento comes with pre-configured grunt tasks for compiling LESS files.
Prerequisites
There are only two major requirements. First of all, you have to set your Magento 2 to the developer or default mode.
Note that with the default mode, you set the Less compilation mode to Server-side Less compilation, which is required for our final goal.
Installing and configuring Grunt
Magento has built-in Grunt tasks configured, but there are still several steps you need to take to be able to use it:
Install node.js to any location on your machine.
Install Grunt CLI tool globally. To do this, run the following command in a command prompt
npm install -g grunt-cli
If you get an error that permission is denied, you’ll need to run the command as sudo
or on Windows, you’ll need to run PowerShell or Command Prompt as an administrator.
Go to the <Magento_root>
directory, copy and paste the contents of the following files:
package.json.sample
intopackage.json
Gruntfile.js.sample
intoGruntfile.js
grunt-config.json.sample
intogrunt-config.json
Install (or refresh) the node.js
project dependency, including Grunt, for your Magento instance. To do this, run the following commands in a command prompt:
cd your_Magento_instance_directory
npm install
npm update
There is also an optional step related to Grunt for “watching” changes automatically, without reloading pages in a browser each time.
To implement this feature, you have to install the LiveReload extension.
Adding themes to Grunt configuration
Add your Custom Theme to Grunt Configuration open this file, in the dev/tools/grunt/configs/themes.js
and add your theme to module.exports like shown below:
module.exports = { <theme>: { area: '<area>', name: '<Vendor>/<theme>', locale: '<language>', files: [ '<path_to_file1>', //path to root source file '<path_to_file2>' ], dsl: 'less' },
Where the following notation is used:
<area>
:- area code, can be eitherfrontend
oradminhtml
.- <vendor_name>:- Your vendor name.
- <theme_name>:- Your theme code that corresponds to the theme directory name.
- <language>:- language specified in the
code_subtag
format, for exampleen_US
. Only one locale can be specified here. To debug the theme with another locale, create one more theme declaration, having specified another value forlanguage
. - <path_to_file >:- The path to the root source file, relative to the directory app/design/frontend/<Vendor>/<theme/>/web.
NOTE: If grunt gives the error “Error: Cannot find module ….”, check the path in your grunt-config.json
file and correct as necessary.
Grunt commands
You just need to execute commands :
- grunt clean :- Remove the theme-related static files in the pub/static/frontend/ and var/ directories.
- grunt exec:- To generate symlinks to the source files to pub/static/frontend/
- grunt less:- Compile CSS files using symlinks published in pub/static/frontend/
- grunt watch:- To track changes in source files, recompile .css files, and reload pages in a browser.
Grunt commands for specific theme
If you are using for a specific theme then execute commands :
- grunt exec : <theme_name> :- To generate symlinks for a specific theme.
- grunt less : <theme_name> :- To use symlinks published for a specific theme.
After running “grunt watch” will watch the *.less files and if some are changed, it will immediately rebuild the CSS file.
Custom Grunt configuration files
There are several ways to declare a custom configuration file.
How to declare a custom config file
There are two options that let you declare a custom config file in a different manner.
Option 1
- Copy the default configuration file to the preferred location in the Magento instance directory. Do not change the default file name.
- Open the
grunt-config.json
file in the Magento root and set configurations object as follows.- key: file alias
- value: path to your custom file
- If your custom configuration file
local-themes.js
is located in the<magento_root>/dev/tools/grunt/configs
directory, the following is already set in yourgrunt-config.json
{ "themes": "dev/tools/grunt/configs/local-themes.js" }
This path is also added to your .gitignore by default. If you are changing this name, It is also necessary to mention that this path is added to your .gitignore.
Option 2
You can also use the other way to declare a custom config file:
In your Grunt related scripts, in the file router, set the alias and path to the custom configuration file. For example, to set the custom themes.loc.js
configuration file, this would look like the following:
filesRouter.set('themes', 'dev/tools/grunt/configs/themes.loc.js');
Note that It must be added earlier, than the get()
method with this alias is called.
In the dev/tools/grunt/configs/
directory, create a copy of the default configuration file. Change its name by adding the “.loc” suffix.
For example, your copy of themes.js
will be themes.loc.js
.
How to use a custom configuration file
Now you have to tell Grunt to use a custom configuration file, instead of the default one, add the following in your script:
- Require file-router:
var fileRouter = require('/files-router');
2. Call the get(%file_alias%)
method to get the configuration file.
var themes = fileRouter.get('themes');
Adding Custom Tasks
Now we’ll go over how to create custom tasks in Grunt that will help make our development faster.
One use case we can automate is when we update a module’s version. Usually, you have to run 3 different tasks:
php bin/magento setup:upgrade php bin/magento setup:di:compile php bin/magento setup:static-content:deploy -f
Instead of running the above commands, we’ll create a new task called upgrade
that will run all these tasks for us.
To create a new task, we need to create a new file in dev/tools/grunt/tasks
. We’ll create a new file there called upgrade.js
The file should export a function that takes grunt
as a parameter:
module.exports = function(grunt) { //Write code here for the custom task };
The reason behind this is that Gruntfile.js
fetches all files in the tasks
directory, and passes them the instance of grunt
.
Now, we’ll declare some functions that will be helpful for us:
const exec = require('child_process').execSync, log = grunt.log.write, ok = grunt.log.ok
exec
: It’s actually the function execSync that allows us to run commands we would run in the shell. We’ll use it to run the commands mentioned above.log
: A function that allows us to output information messages.ok
: A function that allows us to output successful messages.
This time to register our task, we’ll use grunt.registerTask
which takes two parameters: the name of the task and the function that the task will execute once called.
grunt.registerTask('upgrade', function () { });
The first parameter is the command to run, and the second parameter is an options object.
The option we’re passing is stdio
with the value inherit
, which means that the output should be printed to the terminal we’re calling the task from.
We run a grunt task with grunt.task.run
passing it the name of the task. In the end, we’re just outputting a successful message to show that our task is done.
Final code of upgrade.js
should look like this:
module.exports = function(grunt) { const exec = require('child_process').execSync, log = grunt.log.write, ok = grunt.log.ok grunt.registerTask('upgrade', function () { log('Running setup:upgrade...') exec('php bin/magento setup:upgrade', {stdio: 'inherit'}) log('Running setup:di:compile') exec('php bin/magento setup:di:compile', {stdio: 'inherit'}) log('Running deploy...') grunt.task.run('deploy') ok('Upgrade finished!') }); }
Finally, test it out. In the terminal run:
grunt upgrade
If everything is done correctly, the task will run all mentioned commands. This task will make it easier next time you need to upgrade because of a new or updated module! Now, you can automate any task with the same process.
Happy Coding! 🙂
Be the first to comment.