37

Is it possible to pre-generate code for one specific module? I.E. -- I can generate all the code in the system with

php bin/magento setup:di:compile

However, this can take a long time. I'd like to pre-generate only the files for a specific module.

php bin/magento setup:di:compile Pulsestorm_Commercebug

The specific problem I'm trying to solve is working around this issue with some plugins not being recognized in developer/default mode.

2
  • Updated my answer after reading your latest "Open Questions" article. Direct answer to question is: no. It's not complex to solve. It was just not implemented because was never considered needed.
    – Anton Kril
    Feb 8, 2016 at 11:43
  • would be great to get the ability to 'compile' on one module, would save a lot of time when debugging issues in module development. Apr 25, 2016 at 6:25

4 Answers 4

21

Short Answer: No. That is not possible with tools shipped with Magento now.

Explanation: We have to distinguish code generation and compilation. Compiler does both. For both operations we need to read configuration of all other magento modules, otherwise their output will be incorrect or not full.

Compilation for one module does not make sense, as magento will not work with compiled configuration for one module only.

Generation for one module might make sense, but we will have to read configuration and constructor signatures from all other installed modules anyway. Without it not all code might be generated. So such operation would not be much faster than full compilation. We might think of it, but I think the bug you referenced will be fixed before the command is implemented.

2
  • 2
    it's such a pain having to recompile every time a new dependency injection argument is added somewhere during development, is there a way to completely bypass code generation during development?
    – snez
    Jan 29, 2017 at 17:39
  • 9
    You never have to run compiler during development. You will still have to clear /generation directory if you modify method signatures, but no compilation is needed. Compilation is only for switching to production.
    – Anton Kril
    Jan 30, 2017 at 12:19
14

Magento's bin/magento executable is just a Symfony Console component. This means you can find the individual file reponsible for a single command. The naming is always the same so for setup:di:compile you can find the DiCompileCommand.php (setup/src/Magento/Setup/Console/Command/DiCompileCommand.php).

It'll always run the exeucte() method so that's where we need to look. In this function, you'll see an $operations var is set, which is filled by the getOperationsConfiguration() method. This method basically tells the DiCompileCommand what to compile.

The first thing I tried is returning just the application code generator part, like so;

private function getOperationsConfiguration(
    array $compiledPathsList
) {
    $excludePatterns = [];
    foreach ($this->excludedPathsList as $excludedPaths) {
        $excludePatterns = array_merge($excludedPaths, $excludePatterns);
    }

    return [
        OperationFactory::APPLICATION_CODE_GENERATOR => [
            'paths' => [
                $compiledPathsList['application'],
                $compiledPathsList['library'],
                $compiledPathsList['generated_helpers'],
            ],
            'filePatterns' => ['php' => '/\.php$/'],
            'excludePatterns' => $excludePatterns,
        ]
    ];
}

This went pretty well, compilation time was cut down dramatically;

Compilation was started.
Application code generator... 1/1 [============================] 100% 45 secs 308.8 MiB
Generated code and dependency injection configuration successfully.

As opposed to;

Compilation was started.
Interception cache generation... 7/7 [============================] 100% 3 mins 377.0 MiBB8 MiB
Generated code and dependency injection configuration successfully.

Of course, this was to be expected since we cut out a number of things. But you didn't specify which files you want to have generated. Not all files can be generated on a per-module basis, since for example, the Interception classes can be dependent on multiple modules and would therefore give you a limited output of functionality if you'd only run this for one module.

You can find the responsible generators here;

setup/src/Magento/Setup/Module/Di/App/Task/Operation/

Each class has a foreach in it, which will allow you to add an if/else with a continue to skip certain modules/paths. Maybe it would be useful to check out the Symfony Console Component Input Arguments documentation on how to feed arguments into the command.

1
  • 2
    +1 for useful information, but re: "But you didn't specify which files you want to have generated". That's technically correct, but implicit in the question is the desire to have my module's mode generated, and then any additional code that needs to be generated because I've used it in my module. My end goal is not to need to compile the entire system just because I'm working on one module. Jan 25, 2016 at 21:01
3

You can recognize by,

Package -> Module -> registration.php

<?php
    use \Magento\Framework\Component\ComponentRegistrar;
    ComponentRegistrar::register(ComponentRegistrar::MODULE, 'Package_Module', __DIR__);

And than run,

php -f bin/magento module:enable --clear-static-content Package_Module

registration.php will recognize the module and compile your custom module.

I hope this will help you.

1
  • 2
    Useful information, but not what I was looking for. It's not static content I want compiled, it's the generation that runs when you run setup:di:compile. That's a different thing. Jan 19, 2016 at 18:08
-3

When you change your constructor for the class that was generated in previous request it will break. If you are in such needs simply delete var/cache, var/generation and var/di (if exists) and refresh the page. Make sure mode is developer you are working in.

(I am not saying this way magento will not compile or generate codebase, yes it will. Doing this way, it gives a bit relief from running "setup:di:compile" every time you make changes in your routes or classes)

2
  • This seems to be answering a different question. Sep 29, 2016 at 15:41
  • The answer was already given by Anton Kril above, that is very straight and logically true. I just tried to give you an alternate solution which wouldn't let you run command and watch your screen until compilation run. Doing this way you can save your time. Answer is pretty much related to your question. If this is your attitude then no one come up with solutions and thoughts. Oct 5, 2016 at 6:40

Your Answer

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

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