Siaran terdahulu dalam siri ini (Pengenalan yang sangat lembut kepada React) memperkenalkan pembaca kepada sistem rangka kerja React yang sangat baik untuk membangunkan aplikasi web. SvelteKit ialah rangka kerja alternatif. Bagaimanakah ia berbeza daripada React dan adakah ia lebih baik?
Secara fungsional, saya rasa tidak banyak perbezaan. Kebanyakan perkara yang boleh anda lakukan dalam React yang boleh anda lakukan dalam SvelteKit. Dan sebaliknya. Tetapi apabila anda sampai ke butirannya, ramai orang merasakan bahawa SvelteKit mempunyai kelebihan dari segi kemudahan anda mencapai matlamat "reaktif" anda. Svelte bermaksud "elegan" - dan itulah yang dimaksudkan - alat yang langsing, sangat mudah disesuaikan dan praktikal.
Secara peribadi, saya tertarik dengan SvelteKit kerana ia juga cenderung mendorong anda ke arah reka bentuk sisi pelayan - iaitu kod yang berjalan pada pelayan Awan apl web anda dan bukannya dalam penyemak imbas web pengguna anda. Ini adalah ironis kerana kemudahan anda boleh menulis dan menyahpepijat kod sisi klien yang pada asalnya membuatkan saya tertarik dengan pembangunan aplikasi web. Tetapi kemudian saya mendapati betapa enggan labah-labah pengindeksan untuk melaburkan usaha dalam "menghidratkan" kod sisi pelanggan dan menyedari bahawa saya hanya perlu berusaha lebih di sini (lihat penyahpepijatan dalam SvelteKit, di bawah, untuk melihat apa yang diperlukan). Tetapi terdapat sebab lain mengapa anda mungkin mempertimbangkan untuk menggunakan kod sisi pelayan juga. Berikut ialah pasangan:
Sebaik sahaja anda mula menggunakan perkhidmatan pihak ketiga seperti Postmark (penghantaran e-mel) atau Paypal (koleksi pembayaran), anda akan menyedari bahawa adalah bukan idea yang baik untuk memasukkan kod keselamatan mereka dalam kod pihak pelanggan. Jika anda boleh menggunakan "pemeriksa" untuk melihat ini, begitu juga dengan orang lain. Kod yang dijalankan di bahagian pelayan tidak boleh diakses.
kod sebelah pelayan hidup lebih dekat dengan data anda dan berjalan lebih pantas di sini berbanding pada komputer riba pelanggan.
SvelteKit memudahkan anda memainkan lagu untuk menentukan bit aplikasi web anda untuk dijalankan secara setempat dan yang mana untuk dijalankan dari jauh.
Mari kita beralih kepada sesuatu yang lebih konkrit.
Secara luaran, aplikasi web Sveltekit akan kelihatan sama seperti mana-mana aplikasi penyemak imbas klasik - hierarki "halaman" seperti mywebapp/dosomethingwithmyfiles. Ia seperti ini kerana pengguna pelanggan mengharapkan, dan bergantung pada susunan jenis ini. Tetapi di bawah permukaan, aplikasi web SvelteKit menyampaikan susunan ini dengan cara yang sama sekali berbeza kepada aplikasi web React. Dalam React, halaman ini sebenarnya adalah semua bahagian daripada satu papak kod gergasi dan permintaan dihalakan ke sana dengan mengarahkan semula yang beroperasi di antara muka web (jika ayat itu tidak masuk akal kepada anda, lihat Whats a 'Single- aplikasi web halaman?). SvelteKit mencapai ini dengan menggunakan struktur projek anda untuk menentukan struktur halaman anda. Jadi, jika anda ingin mempunyai halaman mywebapp/dosomethingwithmyfiles, anda perlu mempunyai folder bernama dosomethingwithmyfiles dengan fail +page.svelte di dalamnya. Setelah susunan ini disediakan, apl anda yang digunakan menghantar halaman fizikal yang berasingan untuk setiap URLnya.
Berikut ialah contoh struktur folder sumber untuk projek SvelteKit:
projek saya
├───src
│ └───laluan
│ └───dosomethingwithmyfiles
Setelah anda memasang SvelteKit (lihat Svelte untuk Pembangun Baharu), struktur ini akan ditambah dengan jisim fail konfigurasi rumit dan membina folder dll. Tetapi, buat masa ini, tumpuan adalah pada folder laluan. Di sinilah anda menyimpan kod halaman anda - dan di sinilah anda mungkin mula tertanya-tanya sama ada SvelteKit adalah perkara yang sesuai untuk anda. Pegang erat sekarang kerana di sinilah keadaan menjadi agak rumit.
SvelteKit memerlukan anda mengikuti konvensyen penamaan yang sangat ketat untuk kandungan folder halaman. Berikut ialah senarai nama fail yang mungkin dilihat dalam folder dosomethingwithmyfiles:
Pada pandangan pertama, anda mungkin merasakan bahawa ini tidak boleh diterima. Tetapi ambil perhatian bahawa setiap fail +page.svelte layak pada bar editor dengan nama pemilik foldernya, dosomethingwithmyfiles, atau apa sahaja. Tidak begitu sukar untuk mendisiplinkan diri anda untuk menyemak pemilik +page.svelte sebelum anda menyelam dan mula mengedit. Dan apabila anda telah membangunkan satu atau dua projek SvelteKit, anda akan mula menghargai nilai konvensyen dalam mengisytiharkan tujuan susunan itu (seperti yang anda akan lihat sebentar lagi terdapat beberapa variasi )
Sambil anda menyerap kejutan ini, izinkan saya memberi anda sedikit dorongan. Dalam fail +page.svelte yang anda mungkin jangkakan untuk mencari jenis kod yang sama yang anda akan lihat dalam fail React yang setara - campuran panggilan useState eksotik untuk memanipulasi keadaan halaman dan JSX untuk 'bertindak balas' untuk ini dan menjana HTML. Walaupun fail +page.svelte pasti melakukan kerja yang sama, ia berjaya membuang bit "eksotik" dan menggunakan javascript biasa dan HTMl tulen yang tidak dicairkan dengan taburan kata kunci khas. Anda mungkin mendapati ini menyegarkan.
Berikut ialah beberapa lagi nama fail standard yang mungkin anda temui dalam folder dosomethingwithmyfiles:
Menariknya, jika anda pernah mengalami masa lalu kerana terpaksa "memprogram semula" otak javascript anda setiap kali anda bertukar antara menulis kod API Web untuk dijalankan dalam penyemak imbas dan gaya Node.js untuk menjalankan bahagian pelayan dalam fungsi Firebase anda' Saya akan gembira mendengar bahawa, dalam Sveltekit, versi Web API kini sangat gembira untuk menjalankan bahagian pelayan juga.
Sememangnya, anda pasti ingin mengetahui cara anda mengatur sesuatu supaya data yang dibaca oleh fail +page.js berakhir dalam +page.svelte yang berkaitan. Biar saya katakan bahawa, buat masa ini, ini datang dengan sihir SvelteKit. Mekanisme yang tepat hanya akan menjadi jelas apabila saya telah menerangkan susunan SvelteKit untuk menentukan pembolehubah "reaktif". Gantungkan topi anda buat masa ini.
Jika halaman +layout.svelte memerlukan beberapa data, ia boleh mempunyai fail +layout.server.js atendan
Dengan 'pembolehubah reaktif' saya maksudkan item data yang menyebabkan halaman penyemak imbas dipaparkan semula apabila ia berubah. Dengan 'HTML reaktif' saya maksudkan HTML yang diperalatkan untuk menjadikannya bertindak balas kepada perubahan ini.
Dalam React, anda akan ingat, pembolehubah reaktif diisytiharkan menggunakan ungkapan useState yang mentakrifkan pembolehubah sebagai sifat objek keadaan. Pengisytiharan juga menentukan nilai sifat awal dan fungsi untuk mengubahnya.
Berikut ialah contoh - apl web React yang memaparkan pop timbul yang hilang apabila anda mengkliknya:
import React, { useState } from "react"; const [screenState, setScreenState] = useState({popupVisible: true,}); return ( <div> <h1 style={{textAlign: "center"}} onClick = {() => {setScreenState({popupVisible: !screenState.popupVisible})}}> Main Page - Click to toggle popup </h1> {screenState.popupVisible && <div style={{ textAlign: "center", marginLeft: "auto", marginRight: "auto", height: "2rem", width: "25rem", backgroundColor: "gainsboro" }} onClick = {() => {setScreenState({popupVisible: !screenState.popupVisible})}}> <h2> Popup Window - Click to Hide popup</h2> </div> } </div> )
Dalam Svelte (saya kini bercakap tentang bahasa berbanding rangka kerja di mana ia beroperasi) anda mungkin mencapai kesan ini dalam src/routes/demo/+ page.svelte dengan hanya mengisytiharkan popupVisible sebagai pembolehubah javascript
<script> let popupVisible = false; </script> <div> <h1 style="text-align: center" on:click={() => (popupVisible = !popupVisible)}> Main Page - Click to toggle popup </h1> {#if popupVisible} <div style="text-align: center; margin-left: auto; margin-right: auto; height: 2rem; width: 25rem; background-color: gainsboro" on:click={() => (popupVisible = !popupVisible)} > <h2>Popup Window - Click to Hide popup</h2> </div> {/if} </div>
Berikut ialah ringkasan perbezaan utama:
Svelte uses a standard Javascript let declaration to introduce state variables instead of the strange React useState expression
Svelte uses a down to earth #if 'logical expression' keyword to replace the awkward JSX {'logical expression' &&syntax. This makes your code much more readable. Svelte also provides associated else and each keywords.
Svelte uses plain CSS to define HTML classes rather than the perplexing JSX style objects (eg {{textAlign: "center"}}).
Note also that the demo/+pagesvelte file defined above will run directly in the browser as /demo. To run the React version you would have to put some code into an associated src/main.jsx file to define the new route.
Keyboard input in React generally uses the following pattern:
const [myState, setMyState] = useState({myProperty: "",}); function handleChange({ target }) { setMyState({ ...myState, [target.name]: target.value }); }; return ( <input name="myProperty" value={myState.myProperty} onChange={handleChange} /> )
Here, an input labelled as "myProperty" fires a general-purpose handleChange function every time you press a key. In handleChange its value is extracted and applied to the page's state to trigger a re-render.
Svelte thinks this is too complicated and introduces a "bind" keyword to its input syntax. This automatically transmits changes to an associated state variable. A Svelte version of the above thus looks like this:
<script> let myProperty = ""; </script> <input bind:value={myProperty} />
The bind keyword is also used to enable you to create two-way communication between parent and child components. This is a powerful feature.
An interesting feature of Svelte is that it encourages you to use forms and server-side processing for input handling. Thus it's perfectly permissible in Svelte to launch a client-side function like this:
<script> let myProperty = ""; function commitChange() { // Use the global myProperty variable to update server storage } </script> <span>myProperty = </span><input bind:value={myProperty} /> <button on:click={commitChange}>Commit Change</button> />
Svelte docs correctly insist that interactions like this are better handled by forms and server-side processing in a +page.server.js file. Here the validation and submission of the user input can be safely protected from the sort of interference possible in client-based code. Here also, any subsequent processing can be performed with maximum efficiency.
To implement this view, Svelte provide a neat automatic link between a form reading data on a +page.svelte and a function handling the processing of that data in the associated +page.server.js file. Here's an example:
src/routes/login/+page.svelte <form method="POST"> <span>myProperty = </span><input name="myProperty"> <button>Commit Change</button> </form> src/routes/login/+page.server.js export const actions = { default: async (event) => { // TODO handle the processing for the input read by the form on +page.svelte } };
Note that no Javascript has been used in the form - no "on click" or "on submit", for example. The linkage has been established entirely through "Svelte magic".
In practice, of course, a +page.svelte file is likely to want to be the source of multiple "actions". See Svelte Form Actions for details of how Svelte manages this. (Note that Svelte docs are organised under two URLs: kit.svelte.dev for framework topics like routing and svelte.dev for elements of the language itself)
Finally, to conclude this section, suppose you wanted users to be able to call on the service of an action by referencing it directly through a javascript "fetch" (or, at its simplest by launching a parameterised url via the browser - eg https:// mySite/myPage?param1=3 etc). This is where you would use a +server.js file to create an API "endpoint" function. Firebase users might well use such an arrangement where they had previously used a Firebase function. Not the least advantage of this would be that testing and debugging could be done in the Sveltekit server rather than the Firebase emulator.
Each +page.svelte file defines a component, and you mark variables declared here as "props" - ie make them accessible to "consumers" of the component - by adding the export keyword to their declarations. So, if you're still wondering how a +page.svelte file gets its data from +page.server.js - this is how it's done. A +page.svelte file wanting to receive "load" data from its +page.server.js (or +page.js) file just needs to put something like the following in its