Livewire 3 a 4 — čo sa zmenilo

Všetko, čo sa zmenilo medzi Livewire 3 a Livewire 4: nové možnosti, ktoré sa oplatí prevziať, každá nekompatibilná zmena s kódom „predtým / potom“ a kontrolný zoznam samotného upgradu. Vrátane troch zmien, ktoré prejdú vašimi testami a pokazia produkciu.

Livewire 3 → 4 Nekompatibilné zmeny Kontrolný zoznam 14 sekcií

1. Stručne

Livewire 4 je veľké vydanie s malou cestou upgradu. Model komponentu sa nezmenil: PHP trieda, Blade šablóna, stav na serveri, HTML po drôte. Zmenilo sa to, kde komponenty žijú, ako sa píšu a akú časť stránky zasiahne jedna aktualizácia.

Triedne komponenty fungujú ďalej. Jednosúborový formát je predvolený pre nové komponenty, nie nútené prepísanie. Väčšina aplikácií na Livewire 3 sa upgraduje takto: zdvihnúť verziu, opraviť hŕstku nekompatibilných zmien a nové možnosti si osvojovať postupne.

Čo získate

  • Jednosúborové komponenty — trieda a značkovanie v jednom súbore.
  • Ostrovy — oblasti s nezávislým vykresľovaním, bez rozpadu na podkomponenty.
  • Sloty — rodič vkladá značkovanie do potomka, vyhodnocuje sa v kontexte rodiča.
  • Optimistické UIwire:show, wire:text, wire:bind menia DOM bez round tripu.
  • Drag and dropwire:sort, bez externej knižnice.
  • Scoped CSS — štýly komponentu, ktoré nepretekajú.

Čo vás podrazí

  1. Neuzavreté tagy <livewire:…> sa ticho nevykreslia.
  2. Modifikátory wire:model zmenili význam — polia prestanú synchronizovať.
  3. Endpoint aktualizácií sa presunul na /livewire-{hash}/ — lámu sa infraštruktúrne pravidlá.
  4. Modifikátory wire:transition boli odstránené.
  5. Volt sa stal súčasťou jadra.

2. Porovnanie vedľa seba

OblasťLivewire 3Livewire 4
Súbory komponentu app/Livewire/Counter.php + resources/views/livewire/counter.blade.php resources/views/components/⚡counter.blade.php (jeden súbor)
Príkaz na vytvorenie php artisan livewire:make Counter php artisan make:livewire counter
Smerovanie Route::get('/x', Dashboard::class) Route::livewire('/x', 'pages::dashboard')
Čiastočné vykresľovanie Rozpad na podkomponenty Oblasti @island
Sloty Nepodporované {{ $slot }}, <wire:slot name="…">
Drag and drop SortableJS plus lepiaci kód wire:sort
Okamžité UI Alpine.js ručne wire:show, wire:text, wire:bind
CSS komponentu Globálny stylesheet Scoped <style> v komponente
Paralelné akcie Nedostupné #[Async], wire:click.async
Endpoint aktualizácií /livewire/update /livewire-{hash}/update
JS hooky Livewire.hook('request'|'commit') interceptRequest(), interceptMessage()
Volt Samostatný balík Súčasť jadra
Testovanie PHPUnit alebo Pest Odporúčaný Pest, testy môžu ležať vedľa komponentu

3. Upgrade krok za krokom

Bash
# 1. Zdvihnúť závislosť
composer require livewire/livewire:^4.0

# 2. Vyčistiť všetky cache
php artisan optimize:clear

# 3. Spustiť testy skôr, než sa dotknete čohokoľvek ďalšieho
php artisan test

Laravel Shift zautomatizuje veľkú časť mechanickej práce. Či ho použijete alebo nie, prejdite si potom kontrolný zoznam nižšie — tiché zlyhania nástroj označí najhoršie.

Poradie prác, ktoré zvyčajne prebehne hladko

  1. Aktualizovať balík a vyčistiť cache.
  2. Opraviť premenovania v konfigurácii (kapitola 4).
  3. Opraviť smerovanie (kapitola 5).
  4. Nájsť v kóde neuzavreté tagy komponentov (kapitola 6).
  5. Skontrolovať každý wire:model s modifikátorom (kapitola 7).
  6. Aktualizovať infraštruktúrne pravidlá pre nový endpoint (kapitola 8).
  7. Nahradiť odstránené modifikátory wire:transition (kapitola 9).
  8. Migrovať komponenty Volt, ak ste ho používali (kapitola 12).
  9. Spustiť testy znova a prejsť aplikáciu v prehliadači.
  10. Až potom sa pustiť do ostrovov, slotov a jednosúborových komponentov.
Nespájajte upgrade s prepisovaním. Najprv dostaňte aplikáciu do zeleného stavu na v4 s existujúcimi triednymi komponentmi.

4. Premenovania v konfigurácii

Livewire 3Livewire 4Poznámka
layoutcomponent_layoutPoužíva namespace layouts::
lazy_placeholdercomponent_placeholder
smart_wire_keyssmart_wire_keysPredvolená hodnota sa zmenila z false na true
component_locationsPriečinky prehľadávané kvôli komponentom
component_namespacesPomenované korene, napríklad pages::
make_commandJednosúborová alebo triedna generácia
csp_safeBuild pre prísnu CSP
Livewire 4 — config/livewire.php
'component_layout' => 'layouts::app',

'component_placeholder' => 'livewire.placeholder',

'component_locations' => [
    'resources/views/components',
    'resources/views/livewire',
],

'component_namespaces' => [
    'pages' => 'resources/views/pages',
],

// Naďalej generovať triedne komponenty
'make_command' => [
    'type' => 'class',
],

5. Smerovanie

Livewire 3
use App\Livewire\Dashboard;

Route::get('/dashboard', Dashboard::class)
    ->middleware('auth')
    ->name('dashboard');
Livewire 4
use App\Livewire\Dashboard;

Route::livewire('/dashboard', Dashboard::class)
    ->middleware('auth')
    ->name('dashboard');

// Alebo podľa mena komponentu
Route::livewire('/dashboard', 'pages::dashboard')
    ->middleware('auth')
    ->name('dashboard');
Rýchly spôsob, ako ich nájsť: grep -rn "Route::get(.*::class" routes/.

6. Tagy komponentov musia byť uzavreté

Najnepríjemnejšia zmena, pretože zlyháva ticho. Neuzavretý tag komponentu nevykreslí nič — žiadna výnimka, žiadny záznam v logu, len chýbajúci blok na stránke.
Livewire 3 — tolerované
<livewire:user-profile>
<livewire:order-list>
Livewire 4 — povinné
<livewire:user-profile />
<livewire:order-list />
Bash
# Tagy komponentov, ktoré nie sú samouzatvorené
grep -rn "<livewire:[^>]*[^/]>" resources/views/

# Forma cez direktívu @livewire() nie je dotknutá
grep -rn "@livewire(" resources/views/

7. wire:model sa zmenil dvakrát

7.1 Modifikátory riadia synchronizáciu na klientovi

Livewire 3
<input wire:model.blur="title">
<select wire:model.change="status">
Livewire 4 — rovnaké správanie
<input wire:model.live.blur="title">
<select wire:model.live.change="status">

7.2 Už žiadne bublanie z potomkov

Livewire 3 — obal to zachytil
<div wire:model="value">
    <input type="text">
</div>
Livewire 4 — zapnúť výslovne
<div wire:model.deep="value">
    <input type="text">
</div>
Bash
# Každý wire:model s modifikátorom
grep -rn "wire:model\.[a-z]" resources/views/

# wire:model na inom prvku než input je kandidát na problém s bublaním
grep -rn "<div[^>]*wire:model" resources/views/
Vlastné formulárové komponenty — dátumový výber, editor, zabalený select — sú najčastejšími obeťami zmeny bublania, pretože vzor s obalom je presne to, ako sa zvyčajne stavajú.

8. Endpoint aktualizácií sa presunul

Všetky URL Livewire teraz obsahujú hash: /livewire/ sa stalo /livewire-{hash}/.

Táto zmena prejde všetkými testami a pokazí produkciu. Nič vo vašom PHP kóde na cestu neodkazuje, takže sada testov zostáva zelená.

Kde skontrolovať

  • Bloky location v nginxe alebo Apachi
  • Whitelisty WAF a firewallu
  • Pravidlá obchádzania cache CDN
  • Rate limitery viazané na cestu
  • Smerovacie pravidlá load balancera
  • Monitoring a uptime kontroly
  • Záznamy connect-src v CSP
nginx — predtým
location /livewire/ {
    # …
}
nginx — potom
location ~ ^/livewire(-[a-z0-9]+)?/ {
    # …
}

9. wire:transition bol prestavaný

Livewire 3
<div wire:transition.opacity.duration.300ms>
    …
</div>
Livewire 4
<div wire:transition>
    …
</div>
CSS
::view-transition-old(root),
::view-transition-new(root) {
    animation-duration: 300ms;
}
Podpora View Transitions v prehliadačoch nie je univerzálna. Kde chýba, obsah sa jednoducho objaví bez animácie.

10. Zmeny v PHP API

Streaming

Livewire 3
$this->stream(to: '#container', content: 'Hello', replace: true);
Livewire 4
$this->stream('Hello', replace: true, el: '#container');

Mountovanie komponentu

Livewire 3
mount($name, $params = [], $key = null)
Livewire 4
mount($name, $params = [], $key = null, $slots = [])

Nové atribúty

AtribútÚčel
#[Async]Vykonať akciu paralelne
#[Renderless]Preskočiť prekreslenie po akcii
#[Prop]Deklarovať vlastnosť ako props od rodiča
#[Json]Vrátiť dáta priamo do JavaScriptu

11. Zmeny v JavaScript API

Livewire 3
$wire.$js('showToast', { message: 'Uložené' });
Livewire 4
$wire.$js.showToast = { message: 'Uložené' };

Hooky sa stali interceptormi

Livewire 3
document.addEventListener('livewire:init', () => {
    Livewire.hook('request', ({ options, fail }) => {
        options.headers['X-Tenant'] = window.tenantId;

        fail(({ status, preventDefault }) => {
            if (status === 419) {
                preventDefault();
                window.location.reload();
            }
        });
    });
});
Livewire 4
document.addEventListener('livewire:init', () => {
    Livewire.interceptRequest(({ options, fail }) => {
        options.headers['X-Tenant'] = window.tenantId;

        fail(({ status, preventDefault }) => {
            if (status === 419) {
                preventDefault();
                window.location.reload();
            }
        });
    });

    Livewire.interceptMessage(({ component, succeed }) => {
        succeed(() => {
            console.debug('komponent aktualizovaný', component.name);
        });
    });
});
Blade
{{-- Validačné chyby na klientovi --}}
<div x-show="$errors.has('email')" x-text="$errors.first('email')"></div>

12. Volt sa stal súčasťou jadra

VoltLivewire 4
Livewire\Volt\ComponentLivewire\Component
Volt::route()Route::livewire()
Volt::test()Livewire::test()
Service provider VoltOdstrániť
Balík livewire/voltOdstrániť závislosť
Bash
composer remove livewire/volt
Predtým (Volt)
<?php

use Livewire\Volt\Component;

new class extends Component {
    public string $title = '';
};

?>

<div>…</div>
Potom (Livewire 4)
<?php

use Livewire\Component;

new class extends Component {
    public string $title = '';
};

?>

<div>…</div>

13. Osvojenie nových možností

1. Ostrovy na najpomalšej stránke

Predtým — prekresľuje sa celý komponent
<div>
    <div class="card">Tržby: {{ $this->revenue }}</div>
    <div class="card">Úloh vo fronte: {{ $this->queue }}</div>
    <div class="card">Posledná aktivita: …</div>
</div>
Potom — každá karta sa aktualizuje sama
<div>
    @island(name: 'revenue')
        <div class="card">Tržby: {{ $this->revenue }}</div>
    @endisland

    @island(name: 'queue', poll: '5s')
        <div class="card">Úloh vo fronte: {{ $this->queue }}</div>
    @endisland

    @island(name: 'activity', lazy: true)
        @placeholder
            <div class="card skeleton animate-pulse h-48"></div>
        @endplaceholder

        <div class="card">Posledná aktivita: …</div>
    @endisland
</div>

2. Nahradiť round trip klientskými direktívami

Predtým
<button wire:click="$toggle('showFilters')">Filtre</button>

@if ($showFilters)
    <div class="filters">…</div>
@endif
Potom — vôbec bez požiadavky
<button wire:click="$toggle('showFilters')">Filtre</button>

<div class="filters" wire:show="showFilters">…</div>

3. Zahodiť SortableJS

Potom
<ul wire:sort="reorder">
    @foreach ($tasks as $task)
        <li wire:sort:item="{{ $task->id }}" wire:key="task-{{ $task->id }}">
            <span wire:sort:handle>⠿</span> {{ $task->title }}
        </li>
    @endforeach
</ul>

4. Zlúčiť podkomponenty vytvorené len kvôli vykresľovaniu

Ak potomok nemá vlastný stav a nepoužíva sa opakovane, ostrov v rodičovi je ľahší — jeden komponent, jedna trieda, jeden snapshot.

5. #[Renderless] pre neviditeľnú prácu

PHP
use Livewire\Attributes\Renderless;

#[Renderless]
public function trackView(): void
{
    $this->post->increment('views');
}

6. Prevod na jednosúborový formát — až nakoniec

Je to kozmetika. Robte to príležitostne, keď súbor aj tak upravujete, nie ako samostatný migračný šprint.

14. Kontrolný zoznam upgradu

Pred začiatkom

  • Testy prechádzajú na Livewire 3.
  • Samostatná vetva a záloha databázy, ak je prostredie zdieľané.
  • Niekto pripravený prejsť aplikáciu ručne — tiché zlyhania vidí len človek.

Mechanické zmeny

  • composer require livewire/livewire:^4.0
  • php artisan optimize:clear
  • layoutcomponent_layout
  • lazy_placeholdercomponent_placeholder
  • Route::get(…, Component::class)Route::livewire(…)
  • Všetky tagy <livewire:…> samouzatvorené
  • wire:model.blur / .change → pridať .live
  • wire:model na obale → pridať .deep
  • wire:scrollwire:navigate:scroll
  • Modifikátory wire:transition → do CSS
  • Poradie argumentov $this->stream()
  • $wire.$js('name', …)$wire.$js.name = …
  • Livewire.hook(…)interceptRequest() / interceptMessage()
  • Triedy, routy, testy a balík Volt odstránené

Infraštruktúra

  • Location bloky nginx / Apache rozšírené na /livewire-{hash}/
  • Pravidlá WAF, CDN a firewallu aktualizované
  • Rate limitery a monitoring presmerované
  • connect-src v CSP prehodnotený

Overenie

  • Testy zelené
  • Všetky formuláre sa odosielajú a validujú
  • Nahrávanie súborov funguje vrátane indikátora priebehu
  • Tabuľky stránkujú, radia a filtrujú
  • Modálne okná sa otvárajú a zatvárajú
  • Widgety tretích strán v wire:ignore sa inicializujú
  • Konzola prehliadača čistá na hlavných tokoch
  • Aktualizačné požiadavky vracajú 200 v produkcii, nie 403 z WAF
Nasadzujte kanárikovo, ak sa dá. Obe zlyhania, ktoré prežijú zelené testy — neuzavreté tagy a presunutý endpoint — sa v reálnej prevádzke prejavia okamžite.

Oficiálne zdroje

Livewire 4 sa rýchlo vyvíja. Ak sa tento článok a oficiálny upgrade guide rozchádzajú, platí oficiálny zdroj.