-
Notifications
You must be signed in to change notification settings - Fork 0
Project structure
Most useful is a project structure, if we can use it to navigate the codebase and maybe even judge a part of the code-quality. Therefore, it would be best to require a structure, which encourages good design and makes bad design harder to do. A custom structure should also solve other problems we encounter, while developing with Symfony like the migrations problem. Those principles lead to the following proposal of changes:
- Put stuff that changes together in the same directory
- Keep
webpack encore assets,templatesandcontrollertogether asview. - Keep
entities, theirrepositories,migrationsandfixturestogether as thedomainof the application
- Keep
- Solve the migration problem by defining different directories per
environment - Setup a new directory for every feature of the application and group features, if they are strongly related.
This proposal applied would look like this:
├─ bin/
├─ config/
├─ public/
├─ src/
│ ├─ Kernel.php
│ ├─ Domain/
│ │ ├─ Model/
│ │ ├─ Access/
│ │ └─ State/
│ │ ├─ Fixtures/
│ │ └─ Migrations/
│ │ ├─ Development/
│ │ ├─ Test/
│ │ └─ Production/
│ ├─ View/
│ │ ├─ Controller/
│ │ ├─ Templates/
│ │ └─ Assets/
│ ├─ Feature1/
│ ├─ Feature2/
│ └─ Security/
│ ├─ Authentication
│ └─ Authorization
├─ tests/
├─ translations/
├─ var/
└─ vendor/
DataWiz has as any Symfony application two main concerns.
It solves a problem within a certain domain and it presents this solution to a user.
All the structure to do this work is following the Model-View-Controller pattern.
So the default structure is pretty close to generic names to describe the components of this pattern.
Again, there is nothing wrong with that, but it could be made easier.
If we group related files under their tasks, we can identify two types of files.
First is a set of domain related files.
Those will be explained below later.
Second is the view of the user and everything we need to manage this view.
This will be our topic for this section.
What does a developer need to provide a view to something in DataWiz?
He will need a controller, this controller will render a template and this template will be related to assets.
So if a developer changes anything related to the view of DataWiz, he will work with those three type of files.
The default structure makes traversing between those relationships harder than it needs to be.
The templates directory and the assets directory are in the project root, while Controllers are in source/Controllers for us.
Why do we have a source directory, but still have code outside of it?
Those three parts will be one working unit of our application and could therefore be placed together for better understanding.
So if a new developer looks at the codebase he find everything related to change the view of DataWiz in a folder called View.
We saw every file of this change before.
Because changing src into source was also like moving all controllers into a new directory.
# From
App\:
resource: '../source/*'
exclude: '../source/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\Controller\:
resource: '../source/Controller'
tags: ['controller.service_arguments']
# To
App\:
resource: '../source/*'
exclude: '../source/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
App\View\Controller\:
resource: '../source/View/Controller'
tags: ['controller.service_arguments']# From
controllers:
resource: ../../source/Controller/
type: annotation
kernel:
resource: ../../source/Kernel.php
type: annotation
# To
controllers:
resource: ../../source/View/Controller/
type: annotation
kernel:
resource: ../../source/Kernel.php
type: annotation
You just change the config for the templates.
# To
twig:
default_path: '%kernel.project_dir%/source/View/Templates'
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
exception_controller: nullThis is not Symfony's business and is done only in your webpack.config.js.
// TO
.addEntry("app", "./source/View/Assets/Scripts/app.js")
.addEntry("codebook", "./source/View/Assets/Scripts/app-codebook.js")