nWidart / laravel-modules

Module Management In Laravel
https://docs.laravelmodules.com
MIT License
5.49k stars 951 forks source link

How to load Vue Component with InertiaJS in Laravel 8 Modules #1162

Closed lavecart closed 3 years ago

lavecart commented 3 years ago

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:

const app = document.getElementById('app');

new Vue({
    render: (h) =>
        h(InertiaApp, {
            props: {
                initialPage: JSON.parse(app.dataset.page),
                resolveComponent: (name) => require(`./Pages/${name}`).default,
            },
        }),
}).$mount(app);

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!

import { createApp, h } from 'vue'
import { App, plugin } from '@inertiajs/inertia-vue3'

const el = document.getElementById('app')

createApp({
  render: () => h(App, {
    initialPage: JSON.parse(el.dataset.page),
    resolveComponent: name => require(`./Pages/${name}`).default,
  })
}).use(plugin).mount(el)

In Core ( I made this ) module master.blade.php

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Module Core</title>
       <link rel="stylesheet" href="{{ mix('css/core.css') }}">

    </head>
    <body>
        @inertia
        <script src="{{ mix('js/core.js') }}"></script>
    </body>
</html>

CoreController:

use Inertia\Inertia;

class CoreController extends Controller
{
    public function index()
    {
        return Inertia::render('Admin/Index');
    }
}

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'"

yashiroiori commented 3 years ago

Can try with this

image

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 image

yashiroiori commented 3 years ago

Can make work??

enextiarg commented 3 years ago

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');
clickervinod commented 3 years ago

@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`

makusdouglas commented 3 years ago

@enextiarg i have try it but getting the same error. This Error is originated by Mix when running 'npm run dev':

image

Mix is trying to compile .php files. How can i solve this?

sorry my bad english ;)

enextiarg commented 3 years ago

Could you share your webpack.mix.js and config?

makusdouglas commented 3 years ago

@enextiarg, this is my config. I started working with Laravel recently, I'm probably doing something wrong 😄 In resources/js/app.js : image image

In webpack.mix.js : image In webpack.config.js (file generated by Jestream Inertia image

When run yarn dev or watch: image

enextiarg commented 3 years ago

Please check there are missing dependencies, please do

npm i laravel-mix-merge-manifest ignore-loader

SonnySha commented 3 years ago

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

stale[bot] commented 3 years ago

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.

adevapp commented 3 years ago

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?

adevapp commented 3 years ago

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' });
hesammoosapour commented 3 years ago

I just commented import { InertiaApp } from '@inertiajs/inertia-vue' and the error went away.

garbinmarcelo commented 2 years ago

Hi, I'm starting with Inertia now.

How is the integration of Laravel Modules with Inertia? Any difficulties?

Thanks

yashiroiori commented 2 years ago

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

garbinmarcelo commented 2 years ago

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.

yashiroiori commented 2 years ago

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

yashiroiori commented 2 years ago

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

maxonfjvipon commented 2 years ago

@enextiarg, this is my config. I started working with Laravel recently, I'm probably doing something wrong 😄 In resources/js/app.js : image image

In webpack.mix.js : image In webpack.config.js (file generated by Jestream Inertia image

When run yarn dev or watch: image

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...

maxonfjvipon commented 2 years ago

Hey everyone. If you stuck with dynamic import/require problem using modules and Inertia, check this out. Works perfectly.

wadday commented 2 years ago

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) image

Structure arrangements I follow the same as the base structure

base structure image

Modules/Expenses structure image

In base app controller (resources/js/Pages/Welcome.vue) image

in module controller (Expenses/Pages/ExpensesIndex.vue => resources/js/Pages/Expenses/Pages/ExpensesIndex.vue) image

I have created a command to link Modules. image

and finally how the base structure looks like image

Sharing data between module to base app. (ExpensesServiceProvider)

image

base app Middleware (HandleInertiaRequests extends \Inertia\Middleware) image

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) image

Result

base app image

module (expenses) image

in my demonstration, I have shared expenses (empty array) from module share data middleware. (highlighted) image

and finally module components are loaded from Modules. image

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.

enextiarg commented 2 years ago

I like your idea!

diorz38 commented 2 years ago

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) image

Structure arrangements I follow the same as the base structure

base structure image

Modules/Expenses structure image

In base app controller (resources/js/Pages/Welcome.vue) image

in module controller (Expenses/Pages/ExpensesIndex.vue => resources/js/Pages/Expenses/Pages/ExpensesIndex.vue) image

I have created a command to link Modules. image

and finally how the base structure looks like image

Sharing data between module to base app. (ExpensesServiceProvider)

image

base app Middleware (HandleInertiaRequests extends \Inertia\Middleware) image

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) image

Result

base app image

module (expenses) image

in my demonstration, I have shared expenses (empty array) from module share data middleware. (highlighted) image

and finally module components are loaded from Modules. image

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?

AxelGanter commented 2 years ago

Hello everyone, am a little desperate right now. i want to have my inertia pages delivered from the module.

photo_2022-05-28_11-03-31 photo_2022-05-28_11-03-22

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?

AxelGanter commented 2 years ago

seems like Webpack is going right into my Modules-Folder and trying to work on each file

crashlog.txt

AxelGanter commented 2 years ago

image

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

image

irvine48 commented 2 years ago

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.

jobasco commented 2 years ago

@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?

wadday commented 2 years ago

@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

wadday commented 2 years ago

my new implementation main app.js resolve like this. image

base app controller image

in the module controller reference as ModuleName::directory.Filename image

This is vite setup.

also, note that my module resource structure is same as base app resource structure. i

irvine48 commented 2 years ago

@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.

wadday commented 2 years ago

@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.

jobasco commented 2 years ago

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

jobasco commented 2 years ago

@wadday Can you please paste your code? i can't read the screen shot i am having some display problems with my machine.

jobasco commented 2 years ago

@wadday can you please post your whole app.js file? it seems there's a mistake some where.

wadday commented 2 years ago

@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.

in this example, I will use your core module.

  1. Splitting the name (component path) using (::) in the resolve method 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'

jobasco commented 2 years ago

@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'),

wadday commented 2 years ago

@jobasc0 share your repository than only i will be able to help you.

jobasco commented 2 years ago

@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?

wadday commented 2 years ago

@jobasc0 DM me in Twitter @wadday

jobasco commented 2 years ago

@jobasc0 DM me in Twitter @wadday

Thanks

jobasco commented 2 years ago

@jobasc0 DM me in Twitter @wadday

Sorry, i just find out that my twitter account has been suspended

jobasco commented 2 years ago

https://www.facebook.com/iwadday

That will do

gabrieloureiro commented 1 year ago

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.

Screen Shot 2023-02-01 at 14 35 12

ZSSoftwareStudio commented 1 year ago

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.

wadday commented 1 year ago

Try this on app.js (intended for inertiajs earlier than v1.0)

image
 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.

image

vite.config.js

 plugins: [
        laravel({
            input: 'resources/js/app.js',
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: {
        alias: {
            '@': '/resources/js'
        }
    },
jobasco commented 1 year ago

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 { /**

hbend1li commented 10 months ago

Try this on app.js (intended for inertiajs earlier than v1.0) image

 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.

image

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,