Closed lavecart closed 3 years ago
Can try with this
And into controller to load Module vue component The sintax use is: Module/{ModuleName}/{ComponentName} and this search with path Modules/{ModuleName}/Resources/assets/js/Pages/{ComponentName}.vue In the image are: Modules/Brand/Resources/assets/js/Pages/Index.vue
Can make work??
I did some similar, using widart nomenclature in modules
Resolve function in app.js
resolveComponent: (name) => {
let parts = name.split('::')
let type = false
console.log(parts.length)
if (parts.length > 1) type = parts[0]
if(type) return require(`../../Modules/${type}/Resources/assets/js/${parts[1]}`).default
return require(`./Pages/${name}`).default
}
And returning inertia view in controller
return Inertia::render('Test::Dashboard');
So you can use some folder structure of your module eg.
return Inertia::render('MyModule::Clients/Index');
@enextiarg i have try your way but getting below error can u help me
`Module not found: Error: Can't resolve 'path' in 'D:_Projects_Laravel\Play\laravel8\node_modules\dotenv\lib'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default. This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
ERROR in ./node_modules/laravel-mix/src/Mix.js 18:20 Module parse failed: Unexpected token (18:20) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders | class Mix { | /* @type {Mix|null} /
static _primary = null;
| | /**
webpack compiled with 13 errors and 1 warning`
@enextiarg i have try it but getting the same error. This Error is originated by Mix when running 'npm run dev':
Mix is trying to compile .php files. How can i solve this?
sorry my bad english ;)
Could you share your webpack.mix.js and config?
@enextiarg, this is my config. I started working with Laravel recently, I'm probably doing something wrong 😄 In resources/js/app.js :
In webpack.mix.js : In webpack.config.js (file generated by Jestream Inertia
When run yarn dev or watch:
Please check there are missing dependencies, please do
npm i laravel-mix-merge-manifest ignore-loader
Hello,
I finded the solution,
``
render: () =>
h(InertiaApp, {
initialPage: JSON.parse(el.dataset.page),
resolveComponent: (name) => {
let parts = name.split('::')
let type = false
if (parts.length > 1) type = parts[0]
if(type) {
let nameVue = parts[1].split('.')[0]
return require("../../Modules/" + parts[0] + "/Resources/js/Pages/" + nameVue + ".vue").default
}else {
return require(`./Pages/${name}`).default
}
},
}),
})
Hope to help you
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Hello,
I finded the solution,
``
render: () => h(InertiaApp, { initialPage: JSON.parse(el.dataset.page), resolveComponent: (name) => { let parts = name.split('::') let type = false if (parts.length > 1) type = parts[0] if(type) { let nameVue = parts[1].split('.')[0] return require("../../Modules/" + parts[0] + "/Resources/js/Pages/" + nameVue + ".vue").default }else { return require(`./Pages/${name}`).default } }, }), })
Hope to help you
Can you paste your whole app.js?
This is my working version.
require('./bootstrap');
import { createApp, h } from 'vue';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name => {
let parts = name.split('::')
let type = false
if (parts.length > 1) {
type = parts[0]
}
if (type) {
let nameVue = parts[1].split('.')[0]
return import("../../Modules/" + parts[0] + "/Resources/assets/js/" + nameVue + ".vue")
}else {
return import(`./Pages/${name}`)
}
}),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mixin({ methods: { route } })
.mount(el);
},
});
InertiaProgress.init({ color: '#4B5563' });
I just commented import { InertiaApp } from '@inertiajs/inertia-vue'
and the error went away.
Hi, I'm starting with Inertia now.
How is the integration of Laravel Modules with Inertia? Any difficulties?
Thanks
Hi, I'm starting with Inertia now.
How is the integration of Laravel Modules with Inertia? Any difficulties?
Thanks
Any problem with vue or react Can work all modulos or separated Can use same template or each module can have own
Hi, I'm starting with Inertia now. How is the integration of Laravel Modules with Inertia? Any difficulties? Thanks
Any problem with vue or react Can work all modulos or separated Can use same template or each module can have own
Cool, I've been using Laravel Modules for a long time, but only with a blade.
Do you have an online project to show you how it works? At first I will use Vue.
Hi, I'm starting with Inertia now. How is the integration of Laravel Modules with Inertia? Any difficulties? Thanks
Any problem with vue or react Can work all modulos or separated Can use same template or each module can have own
Cool, I've been using Laravel Modules for a long time, but only with a blade.
Do you have an online project to show you how it works? At first I will use Vue.
Not have recently versión of inertiajs with, I change vue with react
https://github.com/yashiroiori/erp-tabler
https://github.com/yashiroiori/aclmanagertabler/tree/master/src/Http/Controllers
Hi, I'm starting with Inertia now. How is the integration of Laravel Modules with Inertia? Any difficulties? Thanks
Any problem with vue or react Can work all modulos or separated Can use same template or each module can have own
Cool, I've been using Laravel Modules for a long time, but only with a blade. Do you have an online project to show you how it works? At first I will use Vue.
Not have recently versión of inertiajs with, I change vue with react
https://github.com/yashiroiori/erp-tabler
https://github.com/yashiroiori/aclmanagertabler/tree/master/src/Http/Controllers
It's easy read documentation of inertiajs to install
@enextiarg, this is my config. I started working with Laravel recently, I'm probably doing something wrong 😄 In resources/js/app.js :
In webpack.mix.js : In webpack.config.js (file generated by Jestream Inertia
When run yarn dev or watch:
Hey there. Did u find a solution? I have the same problem with React. If path is static like ../../Modules/User/Resources/assets/js/${name}
- there is no problem, but when it's dynamic - webpack compiled with 304 errors and 40 warnings...
Hey everyone. If you stuck with dynamic import/require problem using modules and Inertia, check this out. Works perfectly.
hello everyone. My approach to solving this issue is a bit different. (Inertia with modules)
in my base app.js remains the same (note: I have used dynamic import)
Structure arrangements I follow the same as the base structure
base structure
Modules/Expenses structure
In base app controller (resources/js/Pages/Welcome.vue)
in module controller (Expenses/Pages/ExpensesIndex.vue => resources/js/Pages/Expenses/Pages/ExpensesIndex.vue)
I have created a command to link Modules.
and finally how the base structure looks like
base app Middleware (HandleInertiaRequests extends \Inertia\Middleware)
note: the config loads the enabled modules so the main app has only access to enabled modules. (custom config)
Modules/Expenses middleware (ShareDataMiddleware extends \Inertia\Middleware)
base app
module (expenses)
in my demonstration, I have shared expenses (empty array) from module share data middleware. (highlighted)
and finally module components are loaded from Modules.
The idea for this approach is later I want to extract the module as a separate package it will be an easy workflow to integrate into a new project.
hope this is useful.
I like your idea!
hello everyone. My approach to solving this issue is a bit different. (Inertia with modules)
in my base app.js remains the same (note: I have used dynamic import)
Structure arrangements I follow the same as the base structure
base structure
Modules/Expenses structure
In base app controller (resources/js/Pages/Welcome.vue)
in module controller (Expenses/Pages/ExpensesIndex.vue => resources/js/Pages/Expenses/Pages/ExpensesIndex.vue)
I have created a command to link Modules.
and finally how the base structure looks like
Sharing data between module to base app. (ExpensesServiceProvider)
base app Middleware (HandleInertiaRequests extends \Inertia\Middleware)
note: the config loads the enabled modules so the main app has only access to enabled modules. (custom config)
Modules/Expenses middleware (ShareDataMiddleware extends \Inertia\Middleware)
Result
base app
module (expenses)
in my demonstration, I have shared expenses (empty array) from module share data middleware. (highlighted)
and finally module components are loaded from Modules.
The idea for this approach is later I want to extract the module as a separate package it will be an easy workflow to integrate into a new project.
hope this is useful.
can you make some example app with your approach?
Hello everyone, am a little desperate right now. i want to have my inertia pages delivered from the module.
both methods work, but my webpack is unhappy and i can't tell why.
I dont want to have 365 errors when using the dynamic approach, but I need to have my module flexible
can one of you help me?
seems like Webpack is going right into my Modules-Folder and trying to work on each file
this was my solution for now. but still curious, how webpack is working (?)
remember to also add your module Resources (with capital "R") to your tailwind.config.js
package.json
{
"private": true,
"scripts": {
"dev": "vite",
"build": "vite build"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.2",
"autoprefixer": "^10.4.2",
"axios": "^0.27",
"laravel-vite-plugin": "^0.5.0",
"lodash": "^4.17.19",
"postcss": "^8.4.6",
"tailwindcss": "^3.1.0",
"vite": "^3.0.0",
"vite-plugin-windicss": "^1.8.7"
},
"dependencies": {
"@inertiajs/inertia": "^0.11.0",
"@inertiajs/inertia-vue3": "^0.6.0",
"@vitejs/plugin-vue": "^3.0.3",
"vue": "^3.2.36",
"vue-loader": "^17.0.0"
}
}
vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
'resources/**/*.vue',
'resources/**/**/*.vue',
'./Modules/**/Resources/**/*.vue',
],
refresh: true,
}),
],
});
Laravel Controller
return Inertia::render('Admin::Admin/Index', [
'title' => 'Demo From Admin Controller',
'object' => [
'foo' => 'foofoo',
'bar' => 'barbar',
],
]);
app.js
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/inertia-vue3'
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
createInertiaApp({
resolve: (name => {
let parts = name.split('::')
let type = false
if (parts.length > 1) {
type = parts[0]
}
if (type) {
let nameVue = parts[1].split('.')[0];
return resolvePageComponent(`../../Modules/${parts[0]}/Resources/Pages/${nameVue}.vue`, import.meta.glob([
`../../Modules/**/Resources/Pages/**/*.vue`,
]));
}else {
return resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob([
'./Pages/**/*.vue',
]));
}
}),
setup({ el, app, props, plugin }) {
return createApp({ render: () => h(app, props) })
.use(plugin)
.mount(el);
},
});
combine code from Laravel 9.16+ & Vite and some code here. hope this help someone.
@irvine48 I am having this error, Uncaught (in promise) Error: Page not found: ./Pages/core::index.vue at aF (app.9d94ba7e.js:111:98) at resolve (app.9d94ba7e.js:111:17733) at m (app.9d94ba7e.js:39:954) at r0 (app.9d94ba7e.js:39:1028) at app.9d94ba7e.js:111:17694 after following your tutorial, what should i do?
@irvine48 I am having this error, Uncaught (in promise) Error: Page not found: ./Pages/core::index.vue at aF (app.9d94ba7e.js:111:98) at resolve (app.9d94ba7e.js:111:17733) at m (app.9d94ba7e.js:39:954) at r0 (app.9d94ba7e.js:39:1028) at app.9d94ba7e.js:111:17694 after following your tutorial, what should i do?
Check this repo. (this will work but in module controller component path should be from resources/js/Pages as this is a bit old implementation. and it uses symbolic links the module) https://github.com/wadday/laravel-modules-inertia/tree/vite
my new implementation main app.js resolve like this.
base app controller
in the module controller reference as ModuleName::directory.Filename
This is vite setup.
also, note that my module resource structure is same as base app resource structure. i
@irvine48 I am having this error, Uncaught (in promise) Error: Page not found: ./Pages/core::index.vue at aF (app.9d94ba7e.js:111:98) at resolve (app.9d94ba7e.js:111:17733) at m (app.9d94ba7e.js:39:954) at r0 (app.9d94ba7e.js:39:1028) at app.9d94ba7e.js:111:17694 after following your tutorial, what should i do?
Your core:: not being process? Double check that first.
@irvine48 I am having this error, Uncaught (in promise) Error: Page not found: ./Pages/core::index.vue at aF (app.9d94ba7e.js:111:98) at resolve (app.9d94ba7e.js:111:17733) at m (app.9d94ba7e.js:39:954) at r0 (app.9d94ba7e.js:39:1028) at app.9d94ba7e.js:111:17694 after following your tutorial, what should i do?
Your core:: not being process? Double check that first.
Which example have you tried? I have given 2 options. first link to a repo. and second screenshots.
Error: Page not found: ./Pages/core::index.vue make sure you are giving the correct path from the controller.
Hi, thanks a lot for your help, my setup is such a way that my index is directed to my core module so in my main app web routes i have Route::get('/', 'Modules\Core\Http\Controllers\CoreController@index')->name('index'); and in my Core Module controller i have this public function index() { return Inertia::render('core::Pages/index'); } to direct tracfic to my Modules/Core/index.vue and Modules is using the default Nwidart laravel-modules Resources so i have created a Pages folder in assets/js and placed my index.vue file there so don't know if that setup is the problem
@wadday Can you please paste your code? i can't read the screen shot i am having some display problems with my machine.
@wadday can you please post your whole app.js file? it seems there's a mistake some where.
@jobasc0 problem I noticed is how you referring to the component path in the controller.
referring to the resolve portion of the screenshot I've shared.
let pages = name.split('::');
this could expect an array of 2 elements in pages variable.therefore, I am checking
if (pages.length > 1) {
//if pages greater than 1 which means it returns more than 1 item in the pages array in
//your case Core as 1st element and Pages/Index as 2nd element.
//below line extracting 1st element as module (in your case core) and 2nd element as component path (Pages/Index)
const [module, paths] = pages
//here I am splitting the paths using dot (.) and joining forward slash (/).
// meaning in your controller you should define inertia('Core::Index) if the component is within a directory inside Pages //directory you should use dot (.) to separate example: inertia('Core::FolderName.Filename')
//if the file is directly in the Pages folder. inertia('Core::Index')
const moduleFileName = paths.split('.').join('/');
return resolvePageComponent(
`../../Modules/${module}/Resources/js/Pages/${moduleFileName}.vue`,
import.meta.glob('../../Modules/*/*/js/Pages/**/*.vue')
)
} else {
//this is to handle none module pages usually laravel base resource/js/Pages
return resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue'));
}
Note that in the module controller when you give a component name to the inertia method you don't need to define the Pages folder. that part is been handled by the above logic to build the path.
along with the resolve screenshot I have also mentioned this. note that my module resource structure is the same as the base app resource structure.
also, make sure that your folder naming convention is applied when you pass the name from the controller. if the folder name is lower case or upper case or Capitalize or not.
resolvePageComponent is imported from 'laravel-vite-plugin/inertia-helpers'
@wadday Thanks a lot for your help, your code in the screen shot is not working, here is the error code from my site, [plugin:vite:import-glob] Unexpected token (13:99) C:/wamp64/www/laravel/resources/js/app.js:13:99 11 | if (pages.length > 1) { 12 | const [module, paths] = pages const moduleFileName = paths.split(':').join('/'); page = resolvePageComponent( 13 | path: '../../Modules/${module}/Resources/js/Pages/${moduleFileName}.vue', import.meta.glob( pattern: '../../Modules///js/Pages/*/.vue'), | ^ 14 | .then(page = { 15 | page.default.layout = name.startsWith('Auth/') ? undefined : defaultLayout And this is also from online js validator: 2:1 error Parsing error: Unexpected reserved word 'let' 1 | resolve: (name) = { > 2 | let page; let pages = name.split('::'); | ^ 3 | if (pages.length > 1) { 4 | const [module, paths] = pages const moduleFileName = paths.split(':').join('/'); page = resolvePageComponent( 5 | path: '../../Modules/${module}/Resources/js/Pages/${moduleFileName}.vue', import.meta.glob( pattern: '../../Modules///js/Pages/*/.vue'),
@jobasc0 share your repository than only i will be able to help you.
@irvine48 Your code is working but it's showing module first name in small letter, what i mean is my module name is Core but the it's been rendered as core thats why it was working at first unless i manualy changed ${parts[0]} to my module name (Core) is there a work arround for this?
@jobasc0 DM me in Twitter @wadday
@jobasc0 DM me in Twitter @wadday
Thanks
@jobasc0 DM me in Twitter @wadday
Sorry, i just find out that my twitter account has been suspended
That will do
Is there any command to refresh the routes? In my case there are 2 components that are returning 404 even with the others working. I've used php artisan route:clear
, but still not working.
package.json
{ "private": true, "scripts": { "dev": "vite", "build": "vite build" }, "devDependencies": { "@tailwindcss/forms": "^0.5.2", "autoprefixer": "^10.4.2", "axios": "^0.27", "laravel-vite-plugin": "^0.5.0", "lodash": "^4.17.19", "postcss": "^8.4.6", "tailwindcss": "^3.1.0", "vite": "^3.0.0", "vite-plugin-windicss": "^1.8.7" }, "dependencies": { "@inertiajs/inertia": "^0.11.0", "@inertiajs/inertia-vue3": "^0.6.0", "@vitejs/plugin-vue": "^3.0.3", "vue": "^3.2.36", "vue-loader": "^17.0.0" } }
vite.config.js
import { defineConfig } from 'vite'; import laravel from 'laravel-vite-plugin'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [ vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), laravel({ input: [ 'resources/css/app.css', 'resources/js/app.js', 'resources/**/*.vue', 'resources/**/**/*.vue', './Modules/**/Resources/**/*.vue', ], refresh: true, }), ], });
Laravel Controller
return Inertia::render('Admin::Admin/Index', [ 'title' => 'Demo From Admin Controller', 'object' => [ 'foo' => 'foofoo', 'bar' => 'barbar', ], ]);
app.js
import { createApp, h } from 'vue' import { createInertiaApp } from '@inertiajs/inertia-vue3' import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; createInertiaApp({ resolve: (name => { let parts = name.split('::') let type = false if (parts.length > 1) { type = parts[0] } if (type) { let nameVue = parts[1].split('.')[0]; return resolvePageComponent(`../../Modules/${parts[0]}/Resources/Pages/${nameVue}.vue`, import.meta.glob([ `../../Modules/**/Resources/Pages/**/*.vue`, ])); }else { return resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob([ './Pages/**/*.vue', ])); } }), setup({ el, app, props, plugin }) { return createApp({ render: () => h(app, props) }) .use(plugin) .mount(el); }, });
combine code from Laravel 9.16+ & Vite and some code here. hope this help someone.
Hey, I can't run the build command with this vite config file.
Try this on app.js (intended for inertiajs earlier than v1.0)
resolve: (name) => {
let page;
let pages = name.split('::');
if (pages.length > 1) {
//for module path
const [module, paths] = pages
const moduleFileName = paths.split('.').join('/');
page = resolvePageComponent(
`../../Modules/${module}/Resources/js/Pages/${moduleFileName}.vue`,
import.meta.glob('../../Modules/*/*/js/Pages/**/*.vue')
)
} else {
//for none module
page = resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue'))
}
return page
},
in module controller define component path like this. Notice the Module name is seperated with (::) and (.) dot instead of slash.
vite.config.js
plugins: [
laravel({
input: 'resources/js/app.js',
}),
vue({
template: {
transformAssetUrls: {
base: null,
includeAbsolute: false,
},
},
}),
],
resolve: {
alias: {
'@': '/resources/js'
}
},
HI, I have been absent for some time now and i am trying to start a new project but my site is displaying a blank page. My setup is like this. (app.js) import './bootstrap'; import '../css/app.css';
import { createApp, h } from 'vue'; import { createInertiaApp } from '@inertiajs/vue3'; import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers'; import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
createInertiaApp({
title: (title) => ${title} - ${appName}
,
resolve: (name) => {
let page;
let pages = name.split('::');
if (pages.length > 1) {
const [module, paths] = pages
const moduleFileName = paths.split('.').join('/');
page = resolvePageComponent(
`../../Modules/${module}/Resources/views/Pages/${moduleFileName}.vue`,
import.meta.glob('../../Modules/*/*/views/Pages/**/*.vue')
)
} else {
page = resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue'))
}
return page
},
setup({el, app, props, plugin}) {
const vueApp = createApp({render: () => h(app, props)}).use(plugin)
vueApp.mount(el)
return vueApp
},
})
Web Routes use Modules\Core\http\Controllers\CoreController;
Route::get('/', [CoreController::class,'index'], ['canLogin' => Route::has('login'), 'canRegister' => Route::has('register'),])->name('index');
Core Module Controller use Inertia\Inertia;
class CoreController extends Controller { /**
Try this on app.js (intended for inertiajs earlier than v1.0)
resolve: (name) => { let page; let pages = name.split('::'); if (pages.length > 1) { //for module path const [module, paths] = pages const moduleFileName = paths.split('.').join('/'); page = resolvePageComponent( `../../Modules/${module}/Resources/js/Pages/${moduleFileName}.vue`, import.meta.glob('../../Modules/*/*/js/Pages/**/*.vue') ) } else { //for none module page = resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')) } return page },
in module controller define component path like this. Notice the Module name is seperated with (::) and (.) dot instead of slash.
vite.config.js
plugins: [ laravel({ input: 'resources/js/app.js', }), vue({ template: { transformAssetUrls: { base: null, includeAbsolute: false, }, }, }), ], resolve: { alias: { '@': '/resources/js' } },
thanks @wadday , it works well for me. jast replace upper R of Ressource by Lower r.
../../Modules/${module}/resources/views/Pages/${moduleFileName}.vue
,
In Laravel 8 we can load Component with Inertiajs
We initialize Inertia in
app.blade.php
with this@inertia
After that in
app.js
file, we can initialize it like this:Then all components will load from the Pages folder.
Now, my question is:
How can I achieve it in a Module? I want to load Vuejs Components using Inertiajs. In module, this Resources/assets/js/app.js file is empty. If I put the above code in it and create a Pages folder but it's giving me error!
In Core ( I made this ) module
master.blade.php
CoreController:
I have a Page in assets/js/Pages/Admin/Index.vue
I want to load this. But giving me error:
[Vue warn]: Error in created hook: "Error: Cannot find module './Admin/Index'"