Inertia is working nicely in my Laravel App. I’ve set it up as per the Inertia pages, not entirely dissimilar to this >> guide (though there are significant differences in my app).
I’m in the process of trying to modularise >> my app, which again I have no issues with in principle. the Modules functionality works nicely.
The issue I’m having is that I’d like to build my Vue logic inside each of my modules’ “Resources” directory. When I have many modules, this means that the source Vue code will be spread over many “Modules”, meaning that the resolve()
function (in the JS script below) needs to check different locations for the files.
I found this SO >> post on how to “discover” Vue files from different locations. Because import.meta.glob
won’t accept dynamic values, it has to be executed via a switch
or complex array of if
statements (or whatever). This much is fine as well. If I switch the moduleVar
parameter for a hard-coded value in the code below, I can load files from different modules (a few pseudo-cody glitches notwithstanding – code has been simplified to illustrate my problem).
The problem is that I can’t find a way to pass the moduleVar
parameter into the resolve()
function. Conceptually, what I’d like to do is the following:
createInertiaApp({
id: 'app',
resolve: async(name, moduleVar) => { // moduleVar is pseudo-code. I can't find a way to actually pass a parameter in here
const dirs = {
'appfnd': () => import.meta.glob('../../Modules/appfnd/Resources/assets/js/vue/**/*.vue'),
'sales': () => import.meta.glob('../../Modules/sales/Resources/assets/js/vue/**/*.vue',
'std': () => import.meta.glob('./vue/**/*.vue'),
};
const pages = dirs[moduleVar](); // if I hard-code moduleVar to (e.g.) 'sales' my app works
let page;
switch (moduleVar) {
case 'appfnd':
case 'sales':
page = (await pages[`../../Modules/${moduleVar}/Resources/assets/js/vue/${name}.vue`]()).default;
break;
default:
page = (await pages[`./vue/${name}.vue`]()).default;
}
if (page.layout === undefined) {
page.layout = Layout;
}
return page;
},
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(store)
.use(ZiggyVue, Ziggy)
.component('Head', Head)
.component('Link', Link)
.mount(el);
},
title: (title) => title + " - My Lovely App",
});
My idea is that the value would be passed in from Laravel’s Controller, something like this:
<?php
namespace ModulesAppFoundationHttpControllers;
use AppHttpControllersController;
use InertiaInertia;
class PersonController extends Controller
{
private $module = 'appfnd';
public function fnFromLaravelRouter() {
// `moduleVar` parameter in line below, matches variable name that I'd like to pick up in the JS code above.
// This doesn't actually work, but hopefully illustrates what I'd like to achieve
return Inertia::render('modules/appfnd/MyVueFile', ['moduleVar',$this->module]);
}
}
The name
parameter inside the JS resolve()
function is the name of the file passed in from Inertia::render()
, which in the above example is 'modules/appfnd/MyVuFile'
. What I could do is to perform some string manipulation on this value, essentially passing in the data I want via a hack. Buck I want to know if there’s a better way to achieve what I want.
Hopefully I’ve explained clearly enough!