While creating a lot of videos for my Youtube channel, I decided to create an application which I can continue to work on; add more and more features to it and in the end create videos of them to show how to go about developing those features. Everything was working well when suddenly one day I felt a reason to change the way it was structured. In this article, I am going to discuss about the Inferno package and why I decided to go with a composer package based approach instead of an application.
The Inferno app is a Laravel app and the idea was to use this as a quick bootstrap application for any project that I work on. But when I started using this in multiple projects, I came across a hurdle which is – what should I do if I need to change the core piece of the application? I have Authentication, Role and Permission management, Watchdog, Settings etc. and frequently I would want to change the code of the core application. And that was the point when I decided to go with a package development architecture.
Now when you are developing a Laravel packages there will be some questions like How do I structure my code?, How can I use migrations and seeders in my application? Or it can be even managing of assets. So, I am going to share my experience on how I started the development of the Foundation package which is the core part of Inferno and what are the challenges that I faced.
The code structure
I have a strong feeling that the code structure is one of the most important aspect of what ever you are developing. When you are developing something, the code structure should come to you as a second nature. You should not have to think hard about where the file I am looking for is. And hence, I decided to follow what Laravel is following because that structure is well engraved in my memory. Here is a screen shot of the folder structure taken from Github:
As you can see, most of the structure is very similar to any app folder of Laravel application except for some deviations.
Registering dependent packages
Now, my package uses a lot of other packages for functionalities like showing flash messages, managing settings, roles and permissions and even my package heavily depends on Laravel’s Passport for API access. Now, registering then inside app.php is ok if it is a normal app. But when it is a package, I would want it to be automated and then this is how you can register other package’s Service provider and their Facades
Publishing assets and other important files
And apart from the above mentioned things, there is always the necessary item that is assets like CSS, JS, Images etc. And so you can do that very easily now with the “publishes” function as shown below:
Loading Routes and Middleware
Last but not the least, there is a good possibility that your package will have it’s own routes. Which means, you will need to load then on your Service Provider so that the application is aware of the routes that you package is going to introduce. And also, you can also add your own Middleware for the application. Here is how you can add them:
This is the basic structure of the package and how I registered different things for my packages.
Some code style changes
Most of the code for my app didn’t change. In most of the cases, I was just able to copy paste the code from the Inferno app into the package when it came to Controllers, Middleware, Events etc. The only major change which I had to make was in views and how view were called.
Referencing the assets
The assets which are called in views are now a little different. I am calling the assets which are getting publishing and hence I had to define a config variable called asset path. This is necessary because the vendor folder is not available for access from the public folder by default and we don’t want to hack our way into this folder either.
Referencing views inside the controllers
This has also changed a bit because typically we would reference the views based on their path something like ‘pages.user.user-edit‘ which will mean the user-edit.blade.php file is inside ‘resource/views/pages/user‘ folder.
Now, my Inferno app is mainly focused on the functionalities which are primarily for that app itself. When I want to make any change to the core functionality or even fix a bug, I know that I can make that change to the package and when I release a new tag for that package. I can also very make additional packages and the user can choose / opt to either install them or skip them. And based on those modules, I can expose certain additional set of functionalities. Like let’s just say the I want to have a functionality of Blog; ok now either I can build that or use an already available package and code my Foundation package such that if that package is found, then the package is going to behave in a certain way.
All in all a nice way to divide the responsibilities of code and make them modular which brings a lot of benefit.
You can find the package on this url of Github.