我最近更新了一個相當複雜的網路應用程式。該應用程式具有 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中文網其他相關文章!

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

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

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

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

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

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

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

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


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

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

熱門文章

熱工具

SublimeText3 Linux新版
SublimeText3 Linux最新版

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

記事本++7.3.1
好用且免費的程式碼編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

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