Moving everything in /app to /something_else
I am at the very beginning of writing a code generator app that ideally would be able to use the App namespace and the /app directory for generated code, however Laravel, Filament, Jetstream and Fortify have a handful of default files in the /app directory and that use the App namespace.
I am guessing that the reason these files are in /app is because it is anticipated that the developer might want to change the functionality in them and that they are not intended to be replaced during a version update, and that consequently there are no issues about moving these files and editing the files to change the App namespace to something else. Is this guess correct?
I am asking this in the Filament forums as Filament has the most functionality that might assume an App namespace, so I want to be confident that moving it should not create any issues moving forwards.
9 Replies
It took a few hours experimentation but I seem to have managed to achieve this for the welcome page at least. Literally all the base folders except resources (and public and storage which I want to remain where they are) are now in a different subdirectory.
Hey @Sophist-UK
You’re correct that Laravel and its ecosystem uses the
App
namespace and /app
directory. Its designed to be customizable and won’t get overwritten during updates, so moving things around and tweaking the namespace should be fine.
If you want to change the namespace (like to CustomApp
), just update your composer.json
like this:
If you do this dont forget to run composer dump-autoload
. Filament itself shouldn’t care about the namespace, but if you’re using plugins or third-party packages, it’s worth checking if they make any assumptions about App. For your code generator, it’s a good idea to detect the namespace dynamically, so it works no matter what setup someone has.I have actually successfully managed to change the namespace and location of /app to something else.
/app/*, /config, /routes and /test are now successfully in /myproject/core, /bootstrap in /myproject and I plan to create modules /myproject/module1 etc. with their own sets of subdirectories. I had to change .env, artisan, composer.json, public/index.php and mainly /bootstrap/app.php to make the change of directories work.
I also (obviously) had to edit all the files from /app to change the namespace from App* to MyProject\Core*, but that was easy with a global edit.
The only thing I haven't yet been able to do is to move the resources directory and to create separate sources for each module. This is primarily because unlike the App, Bootstrap, Config, Database, Lang, Public, Storage and Environment locations each of which has a
$app-> useXXXPath($path)
method, there is no such method for resources which has to be a fixed resources
subdirectory of the base path. However I think from a pure Laravel code perspective, this only needs to contain the Views
sub-directory structure, with the css and js subdirectories being referred to from e.g. vite and tailwind configuration files. And I think I should be able to define in the ServiceProvider for each module a location for the Views for that module (including core).Hey @Sophist-UK - Laravel doesn’t provide a direct
$app->useXXXPath()
method for resources
, but you might be able to work around it by defining custom view paths in Service Providers. Here’s one way to handle it:
1. Set Custom View Paths in Service Providers For each module, you can add something like this in the register()
method of its ServiceProvider:
This would make views in myproject/module1/resources/views
accessible with the namespace module1::
.
2. CSS/JS with Vite and Tailwind For assets, you can configure Vite or Tailwind to point to module-specific directories. For example, in your vite.config.js
:
You might need to add a Fallback as well but this could allow modular resources folders without straying too far from Laravel’s conventions for views.Yes - that is indeed my plan on my next coding session (later this evening). Having established the structure and got it working, my next steps are to define welcome, registration and login screens and to establish the main UI (Filament panels), persistent/session storage, application settings and then start on the first module.
The only problem with the (same) approach above that we both identified, is that there may still be parts of Livewire or Filament or some other package that still refer to Laravel's "resourcePath()" method, and then we might have some difficulties.
Hey @Sodalis - To handle the potential issues with packages referencing
resourcePath()
, you could override Laravel’s default behavior. In your AppServiceProvider, like this:
This way, any calls to resourcePath()
will point to your custom location instead of the default. What do you think?I would except
useResourcePath()
does not exist.
My next question is what namespace(s) I should use for the various views and components in resources
on the basic Livewire+Jetstream+Filament installation:
I also have the following from App/Views:
Ok - I finally got it working - it looks like I cannot move the bootstrap directory because it is forced to /bootstrap during the application creation.
Hmm - it turns out that App\Models\User is hard coded in various places in filament, fortify, jetstream and maybe eloquent. In which case it seems to be impossible to switch away from the App namespace, and quite possibly from /app too.
I guess I am going to have to put things back and then decide how to generate code for inline testing in a different namespace and generate production code that will be run in a different instance using the App namespace.
Ok - some deep thinking and I came up with a compromise directory structure and namespace mapping that should meet my needs.
I have made most of the necessary changes. Just a few tweaks to make sure that the default paths are correct and that I have added override paths where needed in the ServiceProviders for App and my application core module. Then I can see if it loads.
But that will need to be tomorrow - as I need to sleep.I think it's never harcoded, but always set via config or similar
Just my 2 cents: I did some similar structure as you did when I started my first Laravel project because I wanted everything "to be modular".
Fast forward some years: I ripped everything out again and migrated back to a default folder structure, because it was just causing to much issues.
Definitely hard coded (or at least I didn't find out where it wasn't hard coded). But I did make it work (so far at least) - I created a directory for a module (Base) containing an App sub-directory which has the App namespace and a database sub directory for the Database namespaces. I then subclassed the Laravel ServiceProvider class and added code to do all the stuff packages do to register directories (avoiding registering directories that match locations that are already the ones I defined in my bootstrap/app.php. But I certainly worry that this will come back and bite me later.
I made a subclass of Laravel's ServiceProvider which appears to do the job, however I also just discovered
spatie/laravel-package-tools
which does exactly what I managed to achieve only better, so I will look at switching to that.