Laravel 9.30, weekly updates, and 🔥 tip

Laravel 9.30

Got a minor release late last week and one today bringing us to Laravel 9.30. Here are the highlights:

  • Fix Stringable typehints with Enumerable in #44030
  • Add requiredIfAccepted validation rule in #44035
  • Add Vite asset path generation method in #44037
  • Add ability to discard Model changes in #43772
  • Add ability to determine if attachments exist in #43967
  • Add assertNothingBatched to BusFake in #44056
  • Add read-only filesystem adapter in #44079
  • Fix passing associative array to whereNot in #44083
  • Improve testability of batched jobs in #44075
  • Allow any kind of whitespace in cron expressions in #44110
  • Added scoped filesystem driver in #44105
  • Add --force to all artisan make commands in #44100

You may review the full branch diff on GitHub for a complete list of changes.

This version bump and update is automated for subscribers to a Shifty Plan. If you don't have one of those, be sure to bump your constraint and run composer update to get the latest features.

Weekly Journal

Last week I was on vacation. But on the flight home I made some optimizations to the dynamic queue workers I developed a few weeks ago. I'm now down to one idle server that runs all the job queues and additional workers spawn based on the queue workload.

I also turned the weekly automation into a job batch. This allows me to cancel any previous automation and thus avoid spawning more workers. This can happen when Laravel has a fast follow patch release.

Unfortunately the code I wrote wasn't testable. In this case, the underlying Bus::fake() was missing implementation for several interface methods around job batches. I got the ball rolling with an initial PR and Taylor has followed up with another PR.

I also finished migrating to Vite. Of course I used the Vite Converter. Aside from running npm install, the whole process took about 5 minutes.

Unfortunately I ran into a problem after pushing to production. The @vite Blade directive outputs the <script> tag with a type="module" attribute. This implicitly defers the script. Coming from Laravel Mix, this was a big difference. One I wasn't aware of. This caused some JavaScript reference issues because my inline scripts, which were not deferred, no longer executed after the scripts loaded by Vite. I resolved this by moving the @vite calls to the bottom. But I also could've deferred my inline scripts as well (just more work).

🔥 Tip

Since I didn't do much programming last week I'll point out some code I noticed in Taylor's PR. We all know a PHP function can only return a single value. But this value can actually be complex.

In the case of the new withFakeBatch() method Taylor's adding, he returns a tuple which allows him to return both the job and the job's batch.

return [$this, $this->fakeBatch];

On the receiving side, he can immediately destructure the array to get two values back from the method.

[$job, $batch] = (new ExampleJob)->withFakeBatch();