Understanding Magento 2 Module-Based Architecture

Understanding Magento 2 Module-Based Architecture
Magento 2 Exam Series - Magento Architecture & Customization Techniques: What is a Magento 2 module and how does it work?

Published by Rick Daalhuizen

Let’s start with what a module is, how a module works and how we can register it.

Module overview

The Magento 2 documentation explains the following about modules:

A module is a logical group – that is, a directory containing blocks, controllers, helpers, models – that are related to a specific business feature. In keeping with Magento’s commitment to optimal modularity, a module encapsulates one feature and has minimal dependencies on other modules. - Magento DevDocs - Module overview

Modules and themes are the units of customization in Magento. Modules provide business features, with supporting logic, while themes strongly influence user experience and storefront appearance. Both components have a life cycle that allows them to be installed, deleted, and disabled. From the perspective of both merchants and extension developers, modules are the central unit of Magento organization. - Magento DevDocs - Module overview

The Magento Framework provides a set of core logic: PHP code, libraries, and the basic functions that are inherited by the modules and other components. - Magento DevDocs - Module overview

In short: a module is a logic group (folder) that contains business logic for a specific feature. A module can be installed in 2 places.

  1. In vendor (when installed with composer): vendor/[vendor]/[type]/[type]-[module-name]/[module-name].
  2. In app/ (without composer):
    • as module: app/code/[VendorName]/[ModuleName]
    • as theme: app/design/[type]/[VendorName]/[ThemeName]
    • as language pack: app/i18n/en_EN.csv

When we talk about “type”, we are talking about a module, theme (admin or frontend themes) or language pack.

If a module contains a specific customization that is only related to a specific project, we can put it in app/code/[vendor]/[type]-[module-name].

It’s common to develop our module first in app/ and move it into vendor when a first “stable” release is ready.

Module registration

Magento components, including modules, themes, and language packages, must be registered in the Magento system through the Magento ComponentRegistrar class. - Magento DevDocs - Register your component

When we build a module, it must be registered in order to be recognized by Magento. This is done by means of the Magento ComponentRegistrar class in registration.php. You create this in the root of your module.

  • Register a module
<?php
use \Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::MODULE, '[Vendor_ModuleName]', __DIR__);
  • Register a language pack
<?php
use \Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::LANGUAGE, '[Vendor_PackageName], __DIR__);
  • Register a Frontend or Admin theme, where [area] is frontend or adminhtml.
<?php
use \Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(ComponentRegistrar::THEME, '[area]/[vendor]/[theme-name], __DIR__);

Then we have to autoload our registration.php in /composer.json (root of your module).

{
    "name": [vendor]/[module-name]
    "autoload" {
        "psr-4": { "[Vendor]\\[ModuleName]\\": "" },
        "files": ["registration.php"]
    }
}

After we’ve created our registration.php and added this to our composer autoload, we need to create a /etc/module.xml. It basically tells Magento that it exsist.

The sequence nodes describes the order that the module has to load. This might be usefull when you’re working with plugins, preferences or other dependencies such as layouts.

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="YourCompany_YourModule" setup_version="1.0.0">
        <sequence>
            <module name="TheirCompany_TheirModule" />
            <module name="AnotherCompany_AnotherModule" />
        </sequence>
    </module>
</config>

Modules interaction

The way modules in Magento 2 interact with each other is by means of dependency injection, Service Contracts or Data Service Contracts. An important aspect of interaction is the scope in which the component is located. In other words, a Magento area.

Some benefits of using service contracts is that these contracts ensure a well-defined, durable API that other modules and third-party extensions can implement. Also, these contracts make it easy to configure services as web APIs.

Magento docs: Service contract anatomy

Modules limitation and side effects

However, there’re some limitations and should be considered when you’re working with modules in Magento 2. You should use depends to indicate that a module depends on another module - Module dependencies

  1. A module is responsible for 1 feature.
  2. A module that is dependent on other modules must be explicitly stated in etc/modules.xml, using depends.
  3. When a module is installed or removed it should have no effect on other modules.

Some common errors are:

Magento areas

A Magento area only loads the components that are related to that area. When a component is loaded, you only need to look at the area where the request takes place. This ensures a more optimized process. In addition, it ensures that a component cannot influence different areas.

You can enable or disable an area within a module. If this module is enabled, it injects an area’s routers into the general application’s routing process. If this module is disabled, Magento will not load an area’s routers and, as a result, an area’s resources and specific functionality are not available. – Magento DevDocs - Modules and areas

Magento area types

  1. Adminhtml - Any code you see in the admin panel
  2. Frontend - The storefront (or frontend) has all the template and layout files that you see on the front.
  3. Base - This is the fallback when there is no adminhtml or frontend area.
  4. Crontab - Located in cron.php and loaded with \Magento\Framework\App\Cron.
  5. webapi_rest - Used for REST APIs
  6. webapi_soap - Used for SOAP APIs

To see how areas work, you can find the code Magento/Framework/App/Area.php