Splitting Symfony project into chunks
Why would You even split?
I’ve been (and still am) traveling often between 2 countries. My main desktop PC (more powerful RIG) stays in one country, while I always take my laptop when visiting second one.
Now the problem arose:
- My laptop is around 7 years old and pretty outdated,
- My desktop is also a bit old but has more powerful RIG,
While I can run Symfony server, Websocket server, debugging tools and Vue.js dev tools (with constant on fly compiling and code analyse), it simply chokes on laptop and it literally cries for help.
(over)chunking
Chunking bigger Symfony project is actually very easy. Whenever You need to ad some additional logic to the project think of it this way:
“Can this logic be standalone code? Can I eventually reuse it? Is it maybe to small to split or is it integral part of current workspace?”
You don’t want to end up splitting Your code to much. It might be tempting at first but it just doesn’t make much sense to create small bundle providing service which wraps up other composer package logic. Following this way may even lead to issues where You might eventually end up with tones of packages in Your own repository (because You definitely want to store them somewhere).
Consider an example of having shopping platform:
- The core itself with user login / accounts / shopping logic should remain a core of the project,
- Products providing logic (let it be integration with external services) could be a “Product-Provider-Bundle”,
- “Opinions-Collector-Bundle” could be other package responsible for fetching data from some pages,
You could think of it as Bridge / Connector logic but while it sounds the same there is a tiny difference in implementation here.
There is no Project to which we need to Connect or have Bridge to.
How to
What is chunk? In this case chunk is just another “Standalone Symfony Project” with some extra configuration allowing to Plug-In the bundle to the main project.
To make chunk fully working it requires configuring it as a Bundle, and for that all You need are just 2 files placed in proper directories like on the screenshot below:
There is probably much more to it, but this minimum configuration is all it takes to make the Bundles work.
- Full details are available here: https://symfony.com/doc/current/bundles/extension.html
Installing chunk (bundle) with composer. You can either install Your package like You would normally do it via composer (by for example adding it to Your private Gitlab instance) or You can install the package locally.
With local installation, Composer actually creates link, so You can still work with Your bundle project and it will be automatically updated in the vendor
folder of the project in which You installed You package.
How to install package locally?
- Update the
composer.json
file of the project that will have the bundle installed by providing this section in the root of the mentioned file:
- Set the
name
in thecomposer.json
of the bundle (this name will be used to install the package), for example:"bundle": "volmarg/lingua-bundle"
, - Install the package like You normally would by just calling:
composer require volmarg/lingua-bundle @dev
Activating Bundle. That’s actually just one additional line in the bundles.php
file. Following the above LinguaBundle example, activating (adding) it’s logic is equal to:
With this it’s now possible to call the Controllers & Services in the project, otherwise Symfony will throw Exceptions such as “No service named <ServiceName>
was found”. Provided example bundle configuration allows Symfony to load the additional services.yaml
file.
Issues
The only issue that I’ve found so far is that migrations are not working as they should — meaning that if a bundle has a migrations included then these won’t work in the project which has the bundle installed.
- This however can be fixed by following this guide: https://www.goetas.com/blog/multi-namespace-migrations-with-doctrinemigrations-30/#symfony-integration
Simply explaining
Also keep in mind that the key must be equal to the namespace of the migration file in bundle. So instead of using default namespace DoctrineMigrations
it should become LinguaBundleDoctrineMigrations
.
Summary
For me personally the biggest benefit is that I can work on smaller parts of the project while using the older Laptop.
Also what I found nice is that I’m actually now re-using some of the bundles in another bundles — I often reach a point when I’m like “I would like to have that logic from bundle A”, and It turns out that I’ve already got that logic ready to be re-used.