Categories
Magento

Magento /app/code vs /vendor

Modules in Magento can be located in two places – /app/code and /vendor. Let’s consider what is the difference between them and where it is right to develop your modules. TLDR: it depends on the number of projects in your company.

As already mentioned, Magento implies a modular development principle. That is, each functionality, according to its meaning, should be allocated in a separate module. It implies such a development principle that, ideally, we develop a module with minimization of dependencies on other modules, that is, on pure Magento.

What is the /vendor folder for?

This folder contains third-party modules that were purchased and installed using composer. The vendor folder is entirely controlled by composer and is ignored by git (specified in .gitignore). To install modules there, you need to run composer install, to update – composer update, and so on.

If your company is large enough and has many projects, then it is obvious that you may want to use the same modules in different projects. Then such a company can also be regarded as a full-fledged vendor, and it is also advisable to pack and distribute its modules through composer.

When there are several projects, then each module that is used in these projects can be regarded as a separate mini-project. The module must have its own separate repository, changelog, responsible maintainer, its own ci / cd build procedure. Module versioning in the repository is done by using tags.

What is the /app/code folder for?

If a company has only one project on the Magento platform, then it makes no sense to fully develop each module separately. After all, apart from this project, it will not be used anywhere else. This means that it does not need to create a separate repository, organize versioning using tags, and so on.

In this case, Magento recommends developing the module in /app/code. There you can also create a folder with the name of the company (it will be vendor) and place your modules there.

When developing your modules in /app/code, the entire project exists in one git repository. The version of each module is indicated in Magento way (see the module.xml file).

Performance

Developing modules using composer implies that we can do an optimized autoload dump:

composer dump-autoload --no-dev --optimize --apcu

As you can see, the –apcu key is present here, which signals that the list of classes will be stored in the apcu cache. Loading a list of classes from that cache is extremely fast.

But composer dump-autoload also works with modules that are located in /app/code, so this mechanism will optimize them too.

What are the nuances? If you decide to put your modules in /app/code, then every time for every request that is not cached by Varnish, the glob function will be called 7 times. It is located here:

app/etc/NonComposerComponentRegistration.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

//Register components (via a list of glob patterns)
namespace Magento\NonComposerComponentRegistration;

use RuntimeException;

/**
 * Include files from a list of glob patterns
 */
(static function (): void {
    $globPatterns = require __DIR__ . '/registration_globlist.php';
    $baseDir = \dirname(__DIR__, 2) . '/';

    foreach ($globPatterns as $globPattern) {
        // Sorting is disabled intentionally for performance improvement
        $files = \glob($baseDir . $globPattern, GLOB_NOSORT);
        if ($files === false) {
            throw new RuntimeException("glob(): error with '$baseDir$globPattern'");
        }

        \array_map(
            static function (string $file): void {
                require_once $file;
            },
            $files
        );
    }
})();

glob selects a list of files by the masks below:

registration_globlist.php

return [
    'app/code/*/*/cli_commands.php',
    'app/code/*/*/registration.php',
    'app/design/*/*/*/registration.php',
    'app/i18n/*/*/registration.php',
    'lib/internal/*/*/registration.php',
    'lib/internal/*/*/*/registration.php',
    'setup/src/*/*/registration.php'
];

It can be seen that /app/code is present here and glob is looking for files there. Therefore, the more files and folders are located in /app/code, the longer the fetch will take. If the hard drive is not very fast, the search can be significantly longer. The fact saves a little that disk accesses are cached using the realpath cache mechanism.

On average, a glob lookup operation on a typical project takes about 20-40 milliseconds. This is relatively small, but if you multiply this value by the total number of requests, you get a significant number.

Everyone can see this if they do some profiling, for example with xhprof:

If there are no files and folders in /app/code at all, then this operation takes very little time. This can be an argument in favor of developing modules through /vendor via composer, but it’s up to you whether you are willing to deal with the loss of performance or not.

Leave a Reply

Your email address will not be published. Required fields are marked *