Hyvä 2/25/2016

Step by Step: Setting Up a Frontend Workflow for Magento 2

During the last Firegento Hackathon in Paderborn, I worked in a group that concentrated on the improvements in Magento 2's frontend. Even though an extensive documentation is available, we had our troubles to get started. In order to make it easier to get started with frontend development in Magento 2 in the future, this post shows a step by step guide on how to set up a frontend workflow - and how to avoid possible stumbling blocks that we experienced at the hackathon.

This blog post will not inform about how the frontend mechanisms of Magento 2 work in particular. Instead, it's supposed to be a help for frontend developers who are - like me - in a transition phase, and who are now asked to create a working initial state.

Since there are already different variants and pitfalls during the installation, I recommend to first read our blogpost about Magento 2 installation and do the installation accordingly.

Please remember to activate the Developer Mode. Magento 2 should never be run in the Default Mode, which is a hybrid mode that isn't helpful to anyone really. For further information on modes, take a look at the documentation, or again visit Alan Storm's blog.

bin/magento deploy:mode:set developer

We can now open our browser and take a look at the frontend with its shiny Luma theme.

Project's General Structure

The installation type we chose - "Integrator/Packager" - has all the advantages of Composer. As it's typical for Composer, all Magento modules are stored in
<installation directory name>/vendor/magento
Your own modules or themes can be added in two ways:
  1. via composer in the vendor folder
  2. via the classic approach in the folders app/code and app/design respectively

Set up Grunt Environment

When the installation is finished, the next step is to setup the Grunt environment. All described steps are covered in the official Magento 2 documentation, although there it's not as compactly summarised as it is here.

First of all, we need node.js for our stack.

Then we can install the Grunt CLI

npm install -g grunt-cli

followed by the initialisation of the project specific dependencies

cd <installation directory name> && npm install

To test if everything is correctly installed, use the following call:

$ grunt
Running "default" task

I'm default task and at the moment I'm empty, sorry :/

Done, without errors.


Execution Time (2016-02-01 08:54:44 UTC)
loading tasks  393ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 98%
default          5ms  ▇▇ 1%
Total 400ms

Create Theme Files and use them in Magento 2

In Magento 2, themes are stored in the file system in the following pattern:

app/design/frontend/<Vendor>/<Theme>/

For a minimal setup, we create a theme which inherits everything from Luma. So we create the following files:

// app/design/frontend/<Vendor>/<Theme>/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::THEME,
    'frontend/<Vendor>/<Theme>',
    __DIR__
);
<!-- app/design/frontend/<Vendor>/<Theme>/theme.xml -->
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Vendor: Theme Name</title>
    <parent>Magento/luma</parent>
</theme>

Two trivia we want to change right now, so that we can see right away that we no longer use the original Luma theme:

// app/design/frontend/<Vendor>/<Theme>/web/css/source/_theme.less
@navigation__background: @color-blue1;
@navigation-desktop-level0-item__color: @color-white;

Then we select the theme in Magento 2's backend:

Stores > Configuration > Design > Design Theme

Start the Frontend Workflow with Grunt

Before we can really get to work, we need to tell Grunt that we have just created a new theme. And here is the file entry that does the trick:
// dev/tools/grunt/configs/themes.js
// Add following to config array:
<grunt theme name>: {
        area: 'frontend',
        name: 'Vendor/Theme',
        locale: 'de_DE',
        files: [
            'css/styles-m',
            'css/styles-l'
        ],
        dsl: 'less'
    }
Afterwards, the following steps should be executed exactly once before starting to work:
  1. Clean static files and caches:
    grunt clean
  2. Collect resources and generate static files for our theme:
    grunt exec:<grunt theme name>
  3. Initialise the preprocessing:
    grunt less:<grunt theme name>
  4. Afterwards, reload the frontend page!
The first page view might lead to excessively long load times, since Magento 2 starts the preprocessing in the background which means that a great number of files need to be processed.

Voilà! We have successfully changed Magento's background color and font color in the menu using our own workflow. From now on, we can start the watch task:

grunt watch

If we change a LESS file, Grunt will automatically update all necessary files so we only have to reload the frontend (with the LiveReload browser plugin installed, you won't even need to do that manually).

Questions regarding the Magento 2 Frontend Development

Getting started with the development of Magento 2's frontend can raise many questions: Why have we changed this LESS file in particular? What kind of strange variables are those? What shall I do with all this now? Answering all these questions would go way beyond the scope of this blog post. If you have a concrete question, you are welcome to leave a comment and I'll do my best to answer them or maybe even write another blog post.

We are all fairly new to working with Magento 2. The templating and preprocessing system, introduced by Magento 2, with its own LESS library is very complex. Even while writing these lines, I am still busy to grasp all background information and dependencies to the full extent. For a better start I highly recommend to study the official documentation.

There is also a documentation of the structure, content, coding standards, etc. of the frontend library, stored right inside the source files: lib/web/css/docs/source/README.md

Trouble Shooting

Changing Files

In some cases (e.g. adding new files) it might be necessary to initialize everything again:

grunt clean
grunt exec:<grunt theme name>
grunt less:<grunt theme name>

General "unidentified" problems

The following checklist should reset the system and make changes visible:

  1. Delete the static files relevant for the theme in: pub/static/frontend/ var/view_preprocessed/less/ var/view_preprocessed/source/
  2. Delete the Magento caches (Backend, bin/magento CLI or n98-magerun2)
  3. bin/magento setup:static-content:deploy <lang_LANG>
  4. Start Grunt workflow

Credits

I would like to thank Maria Kern for her friendly adjustment of some missent thoughts.