The original design goal when we introduced Composer was for a Magento site not to depend on Composer. The goal was to allow a site to be constructed with or without Composer. It was also so we could move Magento to any new packaging system that came along later without the code base being overly tied to Composer.
Things have changed over time however. You now cannot just git clone the main repository and build a Magento 2 site without Composer – we use it to load up third party libraries. This is the right thing to do – it makes it easier for example to upgrade underlying libraries. But we still do have the design constraint in place that the only code that should touch composer.json files is the installation flow.
That is, the official current design principle is Composer is used to assemble the code for a site, but is not required to run the site.
For example, there is the load order of modules. This is affected by dependency information from composer.json files and from <sequence> elements in the module.xml file. The dependency information in the composer.json files can help order the loading of modules, but is insufficient as there are dependency cycles. That is module A depends on B and B depends on A. Which module should be loaded first? The <sequence> elements provide that extra level of control over the ordering of modules. Once we eliminate all cycles in dependencies of modules (which may frankly take years to complete as a lower priority) then the <sequence> elements will no longer be required. For now our solution here is for the installation process to use the composer.json file plus module.xml file contents to write out a configuration file in the correct load order. So the store front just gets a nice flat list of modules – it does not have to think about load order any more and does not have to read composer.json files.
In https://github.com/magento/magento2/issues/840 there is a reported violation of the rule that store fronts should not read from composer.json files. The documentation says we follow the rule, the code does not. A version number is being read by store front code from the composer.json file instead of the theme.xml file, which triggered this quick note.
So to summarize, Composer is the technology we are leveraging to worry about dependency information (if you load A, then you have to load B as well) and version compatibility management (version X of A is only compatible with version Y of B). The assembly of a site has been separated from the store front installation itself.
The question I raised on the GitHub ticket above is an example of one of the little decision decisions that needs to be made. Having redundant master data is painful to maintain – e.g. putting version numbers in two locations (the composer.json file and a Magento configuration file). But introducing additional architectural dependencies is also undesirable. For example, if Composer changes the file format at some stage, then the Magento store front code base may break as it has a dependence on the composer.json file format.
This blog post was intended to provide a bit more insight into the internal design principle in this area. Further internal discussions are going to take place before the final call is made. For example, should setup provide version number information of themes extracted from composer.json files, like we do for the load sequence of modules.
Quick edit: “In my experience from training developers and frontend developers I am sure they would appreciate not having to create a composer.json in a theme that is only used within their company.” (Vinai from the GitHub ticket.) Yes, I omitted that from the above. The full installation and deployment process of how to merge locally developed code (as distinct from a Theme extension on Magento Connect etc) is not 100% resolved. We need to finalize if creating composer.json files is mandatory for local modules and themes – e.g. to capture compatibility dependencies.