Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[2.x] Inertia: Automatically publish & register Inertia Middleware #327

Merged
merged 17 commits into from
Oct 15, 2020
Merged

[2.x] Inertia: Automatically publish & register Inertia Middleware #327

merged 17 commits into from
Oct 15, 2020

Conversation

claudiodekker
Copy link
Contributor

@claudiodekker claudiodekker commented Oct 8, 2020

Solves #326

This PR automatically publishes and registers the new HandleInertiaRequests Inertia Middleware with the Http Kernel, to enable automatic asset versioning (cache busting) and error sharing as of default. To take full advantage of this, it also enables versioning as of default in the webpack.mix.js.

Additionally, because Jetstream automatically registers the ShareInertiaData middleware on the 'web' group as priority middleware, this PR also adds logic to ensure the HandleInertiaRequests middleware always runs directly after it when it exists. This gives the user the ability to overwrite the Inertia built-in defaults (such as the user key) if they want to.

Finally, because this Middleware will exist entirely in userland, it allows the user to change it in to any configuration they want, including disabling it entirely.

@claudiodekker claudiodekker changed the title Inertia: auto-configure asset version [1.x] Inertia: auto-configure asset version Oct 8, 2020
src/Http/Middleware/ShareInertiaData.php Outdated Show resolved Hide resolved
@claudiodekker claudiodekker marked this pull request as draft October 8, 2020 13:26
@claudiodekker claudiodekker marked this pull request as ready for review October 8, 2020 17:16
@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 8, 2020

Alright, so, tons of changes. Let me guide you through it.

54db22a

First, I've solved the issue of the Inertia::version being part of the vendor, by moving it to a newly-published InertiaServiceProvider.

Because as a result of this we ended up with a lot of duplicate methods (installFortifyServiceProvider, installJetstreamServiceProvider, installInertiaServiceProvider), I've refactored this methods to a single installServiceProvider($name, $after) method.

7025200

Next, I ran into the dilemma that while Jetstream's Inertia::share would be nice in userland, doing so would cause a lot of repetition. We already had two different files (JetstreamServiceProvider.php, JetstreamWithTeamsServiceProvider.php), and making this change would result in 4 files, as we'd also need one for Inertia as well as one for Inertia with Teams.

To solve this issue, I remembered a thing I learned from @taylorotwell (Laravel ☁️ ) where he used Blade views to 'generate' scripts. I basically did the same thing here by moving the JetstreamServiceProvider into a single 'template', and rendering the file into the state in which it's needed on-the-fly.

Hope this makes sense!

@claudiodekker claudiodekker changed the title [1.x] Inertia: auto-configure asset version [1.x] Inertia: auto-configure asset version & fix Inertia::share issue Oct 8, 2020
@claudiodekker claudiodekker changed the title [1.x] Inertia: auto-configure asset version & fix Inertia::share issue [2.x] Inertia: auto-configure asset version & fix Inertia::share issue Oct 8, 2020
@claudiodekker claudiodekker changed the base branch from 1.x to master October 8, 2020 17:43
@taylorotwell
Copy link
Member

To me it feels odd to call Inertia::share outside of a web request context. For example, I would pretty much expect it to be done in a middleware or controller where there is definitely an HTTP request happening. A console command will fire up all service providers and this will call Inertia::share in that case.

@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 8, 2020

Yeah, I definitely understand, but the inability to define your own defaults and override the user there is kind of problematic, as it'd force you to pretty much drop Jetstream in that situation.

Personally, I don't think its too big of a problem to have them bootstrap like this. Yes, it's maybe not the most efficient, but I kind of see Inertia::share similar to registering container bindings that aren't resolved yet

Perhaps there's something else we can try? Maybe even a change that we can make upstream in Inertia's Laravel adapter?

I'll see if I can find a better solution. In either case, thanks for the feedback 👍

Alright, I went through the Laravel request pipeline, and having it as part of the priority middleware is indeed by far the most preferable approach. I'll revert some of these changes.

@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 8, 2020

Done. I've reverted some of the changes and will update the original message of this PR to reflect this.

In addition, I've briefly had a chat about this topic with @reinink, since we're using Inertia::share inside the AppServiceProvider on our Inertia best-practices / demo repository (PingCRM). I'll create a PR to that repository over the next few days to use Middleware instead, similar to what you're doing here. 👍

@claudiodekker claudiodekker changed the base branch from master to 1.x October 8, 2020 22:10
@claudiodekker claudiodekker changed the title [2.x] Inertia: auto-configure asset version & fix Inertia::share issue [1.x] Inertia: Add Inertia::version for automatic asset cache busting Oct 8, 2020
Also reverts the Inertia\Inertia import, as it was the only 'change' in the file, and will actually cause issues on v2 if the changes get merged into master
@claudiodekker claudiodekker marked this pull request as draft October 9, 2020 08:50
@claudiodekker claudiodekker marked this pull request as ready for review October 9, 2020 12:14
@claudiodekker claudiodekker marked this pull request as draft October 9, 2020 12:37
@taylorotwell
Copy link
Member

Is this ready? If so, can you mark it as ready. I have my GitHub set to filter out draft PRs.

@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 9, 2020

Yeah, it's ready, but @reinink asked me to re-draft it so he could talk to you about it..

@taylorotwell
Copy link
Member

Status? Should this be made active?

@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 14, 2020

Sorry, forgot to post an update here.

Because of the conversation that happened here, we've decided to change Inertia's Laravel adapter to use Middleware as well, resulting in this PR: inertiajs/inertia-laravel#161

The plan is to release that PR tomorrow, at which point I'll update this PR and will mark it ready for review.

Basically, the idea is that this PR will call artisan inertia:middleware (which is similar to artisan make:middleware) to 'generate' an Inertia middleware with certain defaults (automatic versioning like we were introducing here + sharing of errors), which will allow us to remove the entire stub from this PR, making it a lot easier to maintain within Jetstream.

@claudiodekker claudiodekker changed the title [1.x] Inertia: Add Inertia::version for automatic asset cache busting [1.x] Inertia: Automatically publish & register Inertia Middleware Oct 14, 2020
@claudiodekker claudiodekker marked this pull request as ready for review October 14, 2020 22:22
@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 15, 2020

@taylorotwell Alright, everything seems to be working 👍

I also went ahead and split the webpack.mix.js file to be stack-specific, because we already had an ongoing discussion about this over here anyway, and I also didn't really like the idea of touching something that Livewire is also affected by.

@taylorotwell
Copy link
Member

@claudiodekker Can this be re-targeted to master so we can release all of these Inertia improvements at once?

@claudiodekker claudiodekker changed the base branch from 1.x to master October 15, 2020 14:34
@claudiodekker
Copy link
Contributor Author

@taylorotwell Sure, give me 5 mins.. verifying that everything will keep working

# Conflicts:
#	src/JetstreamServiceProvider.php
@claudiodekker
Copy link
Contributor Author

@taylorotwell Done 👍

@taylorotwell
Copy link
Member

I have a feeling all that middleware replacement using PHP_EOL isn't going to work on Windows. 👀

protected function installMiddlewareAfter($after, $name, $group = 'web')
{
$httpKernel = file_get_contents(app_path('Http/Kernel.php'));
$middlewareGroups = Str::before(Str::after($httpKernel, '$middlewareGroups = ['.PHP_EOL), '];'.PHP_EOL);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Particularly here. On Windows I'm not sure this Str::after call will return what you want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I think you're right.. I totally forgot about Windows doing things like this differently.

Let me see if I can adjust this.

@taylorotwell
Copy link
Member

Honestly my gut would be to just replace the HTTP kernel entirely with a stub that contains exactly what you want. It will have some duplication with Laravel itself but would prevent the need for this complicated replace logic.

@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 15, 2020

@taylorotwell What about now? Do you still prefer creating a HTTP kernel stub?

@taylorotwell
Copy link
Member

image

I get this. I assume because you're installing the Inertia dependency but then calling a command in the same process such that for that process it is not installed yet. Make sense?

@taylorotwell
Copy link
Member

Note that error would only occur on a very fresh install so you might not be seeing it if your testing on app that already had Inertia installed.

@claudiodekker
Copy link
Contributor Author

Ah shoot! Yeah, I get what you're saying, it's re-using the container that's already booted.

@taylorotwell
Copy link
Member

Probably you would need to use Symfony Process to run the command.

@taylorotwell
Copy link
Member

OK seems fine to me now. Good to merge?

@claudiodekker
Copy link
Contributor Author

Yep, sure. I just got a pretty crazy idea that might actually be a better alternative to the 'patching' that I'm doing now, but I can just PR that later as it's not breaking 👍

@taylorotwell taylorotwell merged commit 9d9079f into laravel:master Oct 15, 2020
@claudiodekker claudiodekker deleted the solve-326-automatic-versioning branch October 15, 2020 16:14
@claudiodekker
Copy link
Contributor Author

claudiodekker commented Oct 15, 2020

@taylorotwell In case you were curious: I played around with that idea I mentioned for a bit, but I don't think the end result would be better.

Basically, what I wanted to do, is use ReflectionClass::getDefaultProperties to load the Kernel's class properties as an array, grab the middleware group, and add the middleware to that. Then, I'd basically implode the array, and inject it into a Kernel.stub file, followed by overwriting the result to the application's Kernel.php

While this would work just fine, all comments or middleware that's included but 'commented' by default would be stripped out, and without a good way to grab those I think the end result would be less useful compared to what we have now.

@driesvints driesvints changed the title [1.x] Inertia: Automatically publish & register Inertia Middleware [2.x] Inertia: Automatically publish & register Inertia Middleware Oct 19, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants