搜尋
首頁web前端js教程Svelte igration 的經驗與注意事項

Experiences and Caveats of Svelte igration

我最近更新了一個相當複雜的網路應用程式。該應用程式具有 auth、Stripe、i18n、dark/light 模式、PWA 等功能。總體而言,它有大約 30 個頁面和元件,幾乎沒有第三方 npm 套件。

我想指出在將應用程式移轉到 Svelte 5 時我發現非常具有挑戰性的事情。

自動遷移腳本錘

Svelte 提供的自動遷移腳本可以在終端npx sv migrate svelte-5 中使用這個「one-liner」指令為您完成這項工作(在完成所有必要的更新並安裝之後:「@sveltejs/vite - plugin-svelte」:「^4.0.0」和「svelte」:「^5」)。但我並不推薦這種「錘子」的做法。

使用Ctrl Shift P (Windows/Linux) / Shift Command P (Mac) 逐一檔案、逐個元件地進行操作,並使用Migrate Component to Svelte 5 Syntax 指令而是使用VS Code 指令面板。這樣你就會有更多的控制權。

已棄用的 run() 驚喜

腳本無法創造奇蹟。將反應式變數宣告升級到 $state() 通常就可以了。但是,腳本可能很難偵測 $: 是否要轉換為 $driven()/$衍生.by(() => {}) 或 $effect(() => {})。

那麼,你猜怎麼著?使用自動遷移腳本,您最終可能會得到大量 run(() => {})。

例如,想像一個使用以下內容的簡化範例:

<script>
...
   let notext = false;
   $: if (data.completeDoc == 'NoLangVersion') {
      notext = true;
   }
   $: if (data.completeDoc !== 'NoLangVersion') {
      notext = false;
   }
</script>

...
{#if notext}
   {data.userPrefferedLang.noTextWarning}
{:else}
...
{/if}
...

自動遷移腳本將為您提供:

<script>
    import { run } from 'svelte/legacy';
...
    let notext = $state(false);
    run(() => {
        if (data.completeDoc == 'NoLangVersion') {
            notext = true;
        }
    });
    run(() => {
        if (data.completeDoc !== 'NoLangVersion') {
            notext = false;
        }
    });
</script>

有一個很好的小警告,run 函數已被棄用

我猜更好的 Svelte 5 程式碼是這樣的:

<script>
...
    let notext = $derived.by(() => {
        if (data.completeDoc == 'NoLangVersion') {
            return  true;
        }
        if (data.completeDoc !== 'NoLangVersion') {
            return false;
        }
    });
...
</script>

或如果你的程式碼並不複雜,即使是這樣:

<script>
...
    let notext = $derived(
        data.completeDoc == 'NoLangVersion' 
        ? 
        true
        :
        false
        ) 
...
</script>

原因是腳本無法輕鬆地將程式碼轉換為 $categories.by(() => {}),因此它希望使用更髒的方法 $effect()。但 $effect() 僅在客戶端運行,因此腳本使用已棄用的 run 函數。

如果可以的話避免$效應

現在我們得到了最重要的結論。 $effect() 僅在客戶端運行。所以伺服器上沒有 $effect(),用於預渲染頁面和 SSR。

$effect() 不在伺服器上運作!

Svelte 5 文件中應該要強調這一點。

看這兩個例子:

<script>
let a = 1
let b = 2

$: c = a + b
</script>

{c}  // server responds with c == 3
<script>
let a = $state(1)
let b = $state(2)
let c = $state(0)

$effect(() => {
  c = a + b
})
</script>

{c}  // server responds with c == 0

它們不一樣。這帶來了很多挑戰。客戶端在安裝頁面時需要重新評估 c 變數。從伺服器發送的頁面和最終在客戶端進行 DOM 渲染時的頁面看起來會有所不同(SSR、SEO、閃爍問題等)。

因此,請務必嘗試使用 $衍生或 $衍生.by(() => {}) 而不是 $effect()。這會幫你省去很多麻煩。

這與我們被勸阻不要在 SvelteKit 和 SSR 中使用商店時的情況完全相同。

SvelteKit 中的 $effect 與 onMount()

由於 Svelte 5 到來期間給出的範例,您可能會想用 $effect() 取代 SvelteKit 中的 onMount() 。由於已經提到的原因,我暫時不鼓勵這樣做。 onMount 仍然是核心 Svelte 生命週期掛鉤。

$bindable $props 驚喜

另一個令人驚訝的地方是 Svelte 5 非常注意變數值的一致性。如果您將變數作為 prop 傳遞給元件,並稍後在元件中變更此變量,腳本將嘗試使用 $bindable $prop 解決此不一致問題。應通知家長,以便您的應用程式狀態保持一致。

看這個例子:

<script>
...
   let notext = false;
   $: if (data.completeDoc == 'NoLangVersion') {
      notext = true;
   }
   $: if (data.completeDoc !== 'NoLangVersion') {
      notext = false;
   }
</script>

...
{#if notext}
   {data.userPrefferedLang.noTextWarning}
{:else}
...
{/if}
...

自動遷移腳本將要求您使用具有綁定值的元件,以確保父級可以取回更新的值:

<script>
    import { run } from 'svelte/legacy';
...
    let notext = $state(false);
    run(() => {
        if (data.completeDoc == 'NoLangVersion') {
            notext = true;
        }
    });
    run(() => {
        if (data.completeDoc !== 'NoLangVersion') {
            notext = false;
        }
    });
</script>

但也許我們也可以使用更簡單的方法,你猜對了,使用 $衍生():

<script>
...
    let notext = $derived.by(() => {
        if (data.completeDoc == 'NoLangVersion') {
            return  true;
        }
        if (data.completeDoc !== 'NoLangVersion') {
            return false;
        }
    });
...
</script>

:global { } 塊

我在遷移過程中發現的一個非常好的功能是我們現在可以使用 CSS :global 和 block。例如,如果您想在 @html 中設定 HTML 元素的樣式,則使用 :global 進行樣式設定是非常必要的。

所以代替這個:

<script>
...
    let notext = $derived(
        data.completeDoc == 'NoLangVersion' 
        ? 
        true
        :
        false
        ) 
...
</script>

你可以用這個:

<script>
let a = 1
let b = 2

$: c = a + b
</script>

{c}  // server responds with c == 3

樣式作為組件中的道具

在 Svelte 4 中,如果您想要提供 CSS 類別作為元件的 prop,您可以使用 {$$props.class}:

<script>
let a = $state(1)
let b = $state(2)
let c = $state(0)

$effect(() => {
  c = a + b
})
</script>

{c}  // server responds with c == 0

在 Svelte 5 中你可以使用 class={className}:

// parent svelte file
<script>
   import ComponentBinded from './ComponentBinded.svelte';
   import ComponentWithDerived from './ComponentWithDerived.svelte';
   let name = $state('John Wick');
</script>

<p>Name value in parent: {name}</p>

<componentbinded bind:name="{name}"></componentbinded>

<componentwithderived></componentwithderived>

燈塔性能可能下降

當我使用自動合併腳本時,我對應用程式的效能下降感到震驚。有了 Svelte 4,我幾乎獲得了 100% 的成績。直到我手動遷移並仔細考慮如何(主要是如果可能的話如何避免 $effect())後,我的 Lighthouse 分數才再次回到綠色。

最後的話

遷移到 Svelte 5 的時間比我預期的要長。不過,我還沒有將這個新版本投入生產。 Svelte 5 的更新頻率仍然相當高。

希望我的經驗對其他人有用。

以上是Svelte igration 的經驗與注意事項的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Java vs JavaScript:開發人員的詳細比較Java vs JavaScript:開發人員的詳細比較May 16, 2025 am 12:01 AM

javaandjavascriptaredistinctlanguages:javaisusedforenterpriseandmobileapps,while javascriptifforInteractiveWebpages.1)JavaisComcompoppored,statieldinglationallyTypted,statilly tater astrunsonjvm.2)

JavaScript數據類型:瀏覽器和nodejs之間是否有區別?JavaScript數據類型:瀏覽器和nodejs之間是否有區別?May 14, 2025 am 12:15 AM

JavaScript核心數據類型在瀏覽器和Node.js中一致,但處理方式和額外類型有所不同。 1)全局對像在瀏覽器中為window,在Node.js中為global。 2)Node.js獨有Buffer對象,用於處理二進制數據。 3)性能和時間處理在兩者間也有差異,需根據環境調整代碼。

JavaScript評論:使用//和 / * * / * / * /JavaScript評論:使用//和 / * * / * / * /May 13, 2025 pm 03:49 PM

JavaScriptusestwotypesofcomments:single-line(//)andmulti-line(//).1)Use//forquicknotesorsingle-lineexplanations.2)Use//forlongerexplanationsorcommentingoutblocksofcode.Commentsshouldexplainthe'why',notthe'what',andbeplacedabovetherelevantcodeforclari

Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。