Comments (18)
Contrary to Blade, Inertia doesn't look for views, they're just strings.
You have full control over your own app.js
, which is where the views can be resolved as you see fit.
Quick example:
return Inertia::render('my-package::Home/Index');
new Vue({
render: h => h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name => {
if (name.startsWith('my-package::')) {
return require(`../../vendor/my/package/resources/js/Pages/${name.substr(12)}`).default
}
return require(`./Pages/${name}`).default
}
},
}),
}).$mount(app)
Inertia doesn't impose any conventions regarding your frontend code, so I'm not sure what can be done to streamline this.
from inertia-laravel.
I've also hit this. I have some of my optional routes defined inside a package, and the javascript component ends up being published out to resources/vendor/MyPackage/js/Pages/MyPackagePage.js
In the package controller, I can't just do return Inertia::render('MyPackagePage');
because that would look inside resources/js/Pages
, I would need to do something like:
return Inertia::render('../vendor/MyPackage/js/Pages/MyPackagePage');`
which isn't ideal, and doesn't even seem to work.
from inertia-laravel.
This is may solution to call and component from modules and packages
app.js
The structure to call is:
Params to from Module:
Type[Module]/PathToResourcesAssetsJsPages/ViewName.vue
Params to from Package:
Type[Package]/PathToVendorFolder/VendorName/PackageName/PathToResourcesAssetsJsPages/ViewName.vue
Call from modules using https://github.com/nWidart/laravel-modules
Module file structure modulo it's default use the package when create a new module
Packges file structure are usually
from inertia-laravel.
my current implementation for laravel package
resources/js/app.js
new Vue({
render: (h) =>
h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: (name) => {
let splited = name.split('::')
if (splited.length == 1) return require(`./Pages/${name}`).default
let [first, page] = splited
let [author, plugin] = first.split('/')
// '~': path.resolve('vendor')
return require(`~/${author}/${plugin}/resources/js/Pages/${page}`).default
},
},
}),
}).$mount(app);
Author/PackageName/Controller/DashboardController.php
class DashboardController extends Controller
{
public function index()
{
return inertia('author/package-name::Dashboard');
}
}
i hope there is a better and proper way to implement inertiajs return view on laravel package.
from inertia-laravel.
OK. I think I got the answer. Thanks all for the ideas, inspired me to create a plugin.
Inertia Plugin
Warning: This plugin status is experimental, don't use it for the production application.
The plugin page loader for Inertia.js, powered by unplugin, supports Vite and Laravel Mix.
Define the namespace mapping for plugins pages directory, also can be extract namespace from the npm / composer package:
// webpack.mix.js
const InertiaPlugin = require('inertia-plugin/webpack')
mix
.webpackConfig({
plugins: [
InertiaPlugin({
namespaces: ({ npm, composer }) => [
// define namespace mapping:
{ 'my-package-1': 'node_modules/my-plugin1/src/Pages' },
// load namespace from npm package:
npm('my-plugin2'),
// load namespace from composer package:
composer('ycs77/my-php-package'),
],
}),
],
})
The npm package like node_modules/my-plugin2/package.json
:
{
"name": "my-plugin2",
"inertia": {
"my-npm-package": "src/other-pages"
}
}
The composer package like vendor/ycs77/my-php-package/composer.json
:
{
"name": "ycs77/my-php-package",
"extra": {
"inertia": {
"my-php-package": "resources/js/Pages"
}
}
}
Will can be used namespace prefix get the view:
Inertia::render('my-package-1::Page3');
Inertia::render('my-npm-package::Page222');
Inertia::render('my-php-package::PhpPackagePage');
For full usage see the docs.
Try it~ 😊
from inertia-laravel.
I would love this feature too, however i found my way around this which i gonna post here in hope it might help you?
for production i publish the resources to the app's resource folder:
/*
* to publish assets one can run:
* php artisan vendor:publish --tag=web --force
* or use Laravel Mix to copy the folder to public repo of core.
*/
$this->publishes([
__DIR__ . '/public/img' => public_path('img'),
__DIR__ . '/resources/js' => resource_path('js'),
__DIR__ . '/resources/sass' => resource_path('sass'),
$this->getPackageJsonFile() => base_path('package.json'),
$this->getPackageLockJsonFile() => base_path('package-lock.json'),
], 'web');
during development i have npm run watch
running and refering the pages in my package alike (note the copyDirectoryWatched
)
if (! mix.inProduction()) {
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.copyDirectoryWatched('packages/seatplus/web/src/resources/js/Pages/Configuration', 'resources/js/Pages/Configuration')
.webpackConfig({
output : {chunkFilename: 'js/[name].js?id=[chunkhash]'},
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
'@' : path.resolve('resources/js'),
},
},
})
}
Like this you are able to work out your package as you would do it in the main application.
from inertia-laravel.
The only problem with that is that the app.js
would need to be aware of all the possible packages in order to resolve the paths, rather than the package being able inject themselves.
The suggestion from OP seems better in terms of isolation / injection, you would tell inertia that you have views in a package folder, and then when you call Inertia::render('my-package::Component')
, it could internally check the map of namespaces and convert the component argument before passing it down to the javascript.
This would allow the javascript resolveComponent
function to remain unaware of the existence of any packages.
from inertia-laravel.
I've spent a bit longer on this today and realised @sebastiandedeyne is right. You need the requires to have at least the partial path to allow webpack to statically analyse the lazy load possibilities, so doing it inside the componentResolver makes a lot more sense.
from inertia-laravel.
Just wondering at this point a guide about creating packages with Inertia would be a nice addition :)
from inertia-laravel.
For future reference here is my approach. Built a package as a standalone dashboard using inertia, where target app does not has inertia or laravel mix.
https://github.com/robsontenorio/lighthouse-dashboard
from inertia-laravel.
@vortechron this looks very promising i am likely ditching my approach in favors of yours
from inertia-laravel.
i gave @vortechron 's solution a try and i wasn't satisfied. running dev/prod with npm took way to long.
from inertia-laravel.
I'm also interested on this feature. Has anyone found a workaround for this?
from inertia-laravel.
I'm also interested on this feature. Has anyone found a workaround for this?
Actually work with modules package + inertiajs + vue/react + bootstrap/tailwind
from inertia-laravel.
@yashiroiori can you explain how did you manage to setup the packages, so that views are loaded with Inertia?
from inertia-laravel.
@yashiroiori can you explain how did you manage to setup the packages, so that views are loaded with Inertia?
+1
from inertia-laravel.
I think this can be done using symlink
and I had it working on my local but there are few things need to be addressed.
This is an example directory
.
├── app
├── resources/
│ └── js/
│ ├── app.js
│ └── Pages/
└── vendor/
└── my-package/
├── config/
├── src/
│ └── ServiceProvider.php
└── js/
├── ComponentA.vue
└── ComponentB.vue
In your package ServiceProvider
, register the component hint path
Inertia::loadComponentsFrom(__DIR__.'/../js', 'my-package');
Then have artisan command similar to storage:link
to generate the symlink from vendor/my-package/js
to resources/js/Pages/vendor
.
├── app
├── resources/
│ └── js/
│ ├── app.js
│ └── Pages/
│ └── vendor/
│ └── my-package -> symlink to vendor/my-package/js/
└── vendor/
└── my-package/
├── config/
├── src/
│ └── ServiceProvider.php
└── js/
├── ComponentA.vue
└── ComponentB.vue
In your controller you can use something like this
Inertia::render('my-package::ComponentA');
It will replace the the component from my-package::ComponentA
to vendor/my-package/ComponentA
and you don't have to update your app.js
The command can be added to composer post-autoload-dump
script to generate the symlink
automatically. However there is a case when assets are published to resources
folder, the symlink need to be updated also. The good news is there is VendorTagPublished
event for this but the bad news is it only available since Laravel 8. I can create a PR for this when I have time to address this issue.
How do you guys think about this approach?
from inertia-laravel.
my current implementation for laravel package
resources/js/app.js
new Vue({ render: (h) => h(InertiaApp, { props: { initialPage: JSON.parse(app.dataset.page), resolveComponent: (name) => { let splited = name.split('::') if (splited.length == 1) return require(`./Pages/${name}`).default let [first, page] = splited let [author, plugin] = first.split('/') // '~': path.resolve('vendor') return require(`~/${author}/${plugin}/resources/js/Pages/${page}`).default }, }, }), }).$mount(app);Author/PackageName/Controller/DashboardController.php
class DashboardController extends Controller { public function index() { return inertia('author/package-name::Dashboard'); } }
i hope there is a better and proper way to implement inertiajs return view on laravel package.
when i try to use this. i have an error javascript heap out of memory
looks like it will compile all the package.
from inertia-laravel.
Related Issues (20)
- image upload help HOT 2
- Laravel 11 support HOT 2
- There is no automatic follow protocol, http is used under https, how to solve it HOT 4
- Laravel 11 update and Nova issue HOT 2
- Vue Watch not working upon redirect route HOT 2
- Problem with SSR HOT 1
- Force app.blade.php to reload HOT 2
- Should Inertia middleware call session()->setPreviousUrl? HOT 6
- - HOT 1
- redirection to /dashboard after login does not work HOT 1
- Prevent a webpage from navigating away HOT 1
- Release notes for 1.0 could make it more clear that "Fix URL generation (#592)" is a breaking change HOT 5
- Ziggy2.0 and Laravel11 and Breeze for Inertia + React, TypeScript and SSR starter kit throws error on initial setting HOT 2
- assertInertia() fails when testing Inertia visits HOT 1
- Inertia components/hooks wrapped with redux Provider stopped working HOT 2
- client-side validation libraries HOT 1
- SSR high CPU usage HOT 1
- Serve Connection Reset HOT 1
- Default Layout HOT 1
- adding to HandleInertiaRequests->share array no longer works in version 1.2.0 HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from inertia-laravel.