8

Is there currently a way to load different modules per environment, for instance to load Alan's CommerceBug extension only when I'm in my development environment?

Like in Magento 1 I can .gitignore the modules files in app/code but I can not ignore changes to app/etc/config.php easily via git.

It does not seem possible to load modules defined in your env.php as the Magento\Framework\App\DeploymentConfig\Reader load method only uses array_merge, instead of some sort of deep merge, to merge the file data and throws an Exception if similar keys are found.

/**
 * Loads the configuration file
 *
 * @param string $fileKey
 * @return array
 * @throws \Exception
 */
public function load($fileKey = null)
{
    $path = $this->dirList->getPath(DirectoryList::CONFIG);
    $fileDriver = $this->driverPool->getDriver(DriverPool::FILE);
    $result = [];
    if ($fileKey) {
        $filePath = $path . '/' . $this->configFilePool->getPath($fileKey);
        if ($fileDriver->isExists($filePath)) {
            $result = include $filePath;
        }
    } else {
        $configFiles = $this->configFilePool->getPaths();
        $allFilesData = [];
        $result = [];
        foreach (array_keys($configFiles) as $fileKey) {
            $configFile = $path . '/' . $this->configFilePool->getPath($fileKey);
            if ($fileDriver->isExists($configFile)) {
                $fileData = include $configFile;
            } else {
                continue;
            }
            $allFilesData[$configFile] = $fileData;
            if (!empty($fileData)) {
                $intersection = array_intersect_key($result, $fileData);
                if (!empty($intersection)) {
                    $displayMessage = $this->findFilesWithKeys(array_keys($intersection), $allFilesData);
                    throw new \Exception(
                        "Key collision! The following keys occur in multiple config files:"
                        . PHP_EOL . $displayMessage
                    );
                }
                $result = array_merge($result, $fileData);
            }
        }
    }
    return $result ?: [];
}

I found a very early github issue raised by @mzeis on https://github.com/magento/magento2/issues/7 which talks about multiple configurations per environments but this has been closed.

It would be possible to do some git hooks which call bin/magento module:enable and module:disable but this seems a very roundabout way to achieve truly environment dependant configuration.

2 Answers 2

0

I'll answer this based on both ways of installing modules in Magento. However, in both cases, you should gitignore the app/etc/config.php file and have it generated on each environment.

Installed using Composer

You should install the module in the require-dev section of composer as opposed to the require section (you do this using composer require --dev module/name). Then in your production environment when you run composer install you should include the --no-dev parameter.

Installed by deploying to app/code/Module/Name

You would handle this method the same as in M1. Just gitignore the directory.

4
  • When you say "have it generated on each environment", how would you go about this when "deploying to app/code/Module/Name" is there a command to do this? Commented Oct 12, 2016 at 20:45
  • app/etc/config.php is auto-generated/updated when you run php bin/magento setup:upgrade or php bin/magento module:enable <modulename>. If the module doesn't exist (you gitignored it) then it won't be added to config.php (or it will be removed if it previously existed) Commented Oct 13, 2016 at 22:08
  • After trying some different things, the file does need to exist and needs to have minimum a minimum of one entry in the module array for it to generate correctly, otherwise it throws an exception Commented Oct 17, 2016 at 12:26
  • It seems something has changed since I initially did this. However, I would still strongly recommend not tracking the config.php file in git. You would only have an issue on first run of an environment and then only if you were trying to use an existing env.php along with an existing DB. If you were doing that, you should use the existing config.php as well. Commented Oct 18, 2016 at 16:08
1

If you're using composer to install a module, then the only non-hack way to disable it is using php bin/magento module:disable Vendor_Module somewhere in your deployment process.

If you're not using composer and the module resides under app/code/Vendor/Module then you should ignore it in your vcs. This does imply that you have to keep a copy of that module somewhere other than in your vcs.

The second option seems to be best. If you don't want that module present or active on your production environment then it can be seen as a development tool and should not be part of your project in vcs.

I would also advise to ignore this type of module in your global ignore file rather than on a per-project basis. This prevents slip-ups.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.