Legenda Kerangka Kekuasaan

Baru-baru ini, tren "menghilangnya kerangka kerja" semakin populer, lokomotif yang, tanpa diragukan lagi, dapat dianggap SvelteJS - kerangka waktu kerja dan kompiler javascript vanilla.

Terlepas dari kenyataan bahwa secara konseptual Svelte sangat sederhana, dan bahkan lebih mudah digunakan, banyak pengembang bertanya-tanya apa fitur pembunuh kerangka ini, dan seluruh pendekatan? Mengapa ini bukan "kerangka kerja javascript lain"?

Dalam artikel ini saya akan berbicara tentang salah satu dari banyak kekuatan super Svelte yang dapat dengan serius membuat hidup Anda lebih mudah.

Mari kita cari tahu, tapi pertama-tama aku akan memberitahumu satu legenda ...



Legenda Kerangka Kekuasaan


Beberapa kerangka kerja diciptakan oleh orang-orang dari Google dan Facebook, yang lain - dudes keren, tetapi semua di bawah "perhatian" Rich Harris .

Sembilan kerangka diciptakan untuk manusia, tujuh tampaknya untuk kurcaci. Tiga kerangka kerja lainnya (reaksi, sudut, sudut) adalah untuk peri.

Setelah membuat kerangka kerja dan mengimplementasikannya dalam ribuan proyek, Rich Harris secara pribadi dan diam-diam membuat satu kerangka kerja ...

Satu kerangka kerja untuk mengatur semuanya,
Satu kerangka kerja untuk menemukannya,
Satu kerangka untuk membawa semuanya
Dan bersama-sama ikat mereka.

- Penguasa Kerangka

Masalah


Saya yakin bahwa banyak dari Anda yang telah serius dan lama terlibat dalam pengembangan front-end telah berulang kali menghadapi masalah dalam memilih alat untuk proyek Anda saat ini dan / atau berikutnya.
Variasi dari semua jenis paket, utilitas, paus, kerangka kerja, perpustakaan, dan solusi lainnya berada di luar skala yang belum pernah ada sebelumnya. Dan yang terpenting, semua gerakan ini terus melaju.

Semua ini, satu atau lain cara, berlaku untuk pilihan kerangka kerja. Mungkin tidak salah jika saya berasumsi bahwa hanya beberapa tim dan perusahaan modern memulai proyek baru tanpa menggunakan kerangka js. Tentu saja, ketika datang ke aplikasi web modern, bukan hanya situs web. Dan semuanya akan baik-baik saja jika begitu banyak dalam proyek Anda tidak bergantung padanya.


Menilai sendiri, komposisi dan karakteristik tim sangat tergantung pada kerangka yang Anda pilih, dan seluruh proses berburu tentu tergantung. Kadang-kadang anggaran dan jadwal bahkan bergantung pada ini. Singkatnya brrr.

Tetapi masalah sebenarnya dimulai, jika di suatu tempat di tengah proyek, Anda menyadari bahwa Anda telah membuat pilihan yang salah. Sesuatu tidak tumbuh bersama dan berputar. Kerangka kerja ini membutuhkan sedikit lebih banyak waktu untuk dikuasai, tim yang sedikit lebih besar, ternyata sedikit kurang cepat, sedikit tidak cocok untuk tujuan atau gaya pengembangan Anda, dll. Dan yang paling penting, sekarang proyek Anda 100% terikat pada kerangka kerja ini dan Anda tidak bisa hanya mengambil dan menulis ulang pada hal lain.

Bahkan yang lebih ofensif, ketika tetap menyelesaikan proyek dengan sukses, Anda memahami bahwa secara umum, Anda tidak terlalu bahagia. Dan mungkin, kami tidak ingin menulis proyek berikutnya pada kerangka kerja yang sama. Jadi, semua solusi "yang digunakan kembali" yang sedang kita perjuangkan bisa dibuang ke dalam pipa.

Sebenarnya, dengan itu, dengan kode bisnis yang mengimplementasikan tugas bisnis tertentu, berfungsi dengan baik. Tapi Anda menulis "% insert your% cool dengan blackjack dan cewek dengan tanggung jawab sosial yang rendah", dan Anda ingin menggunakannya dalam proyek berikutnya, tetapi infeksi ini terkait erat dengan kerangka kerja saat ini di mana Anda sudah melihat satu jenis.

Variasi lain dari masalah yang sama - bayangkan Anda adalah perusahaan besar, seperti Yandex. Anda memiliki banyak proyek, bahkan beberapa di antaranya hanya diketahui oleh beberapa karyawan, dan setiap proyek telah mengalami semua yang saya jelaskan di atas. Masalahnya adalah bahwa semua proyek ini duduk dan membenci kerangka kerja berbeda yang awalnya mereka pilih.

Dan inilah kepemimpinan Anda yang luar biasa, memutuskan untuk bersaing dengan Google Material Design dan mengirim Anda pada perang salib ke antarmuka beraneka ragam proyek Anda untuk membawanya ke penyebut yang sama. Perancang licik telah menggambar tombol dan penyeleksi baru dan mencoret-coret ribuan halaman pedoman untuk kit UI tunggal baru dari komponen Anda. Kawan-kawan Hore!

Bukan kehidupan, tapi dongeng, kan? Tetap hanya sampai pada bagaimana cara menarik semua komponen baru ini pada semua proyek yang sudah Anda tulis pada semua kerangka kerja yang mungkin. Jika benar-benar ada banyak waktu dan uang dan ada keinginan estetika, dan yang paling penting keyakinan bahwa "semuanya harus dipersatukan," maka Anda dapat menempatkan beberapa lusin tim untuk menulis ulang semuanya lagi, misalnya, pada React. Ini benar, karena omong kosong yang Anda tulis 2-3 tahun terakhir sudah usang secara moral, tetapi Bereaksi akan selamanya. Baik, baik)

Ada cara lain. Anda dapat menulis kit UI baru yang luar biasa pada satu kerangka kerja, membuat perpustakaan komponen yang dapat digunakan kembali, seolah-olah, dan kemudian hanya menggunakan kit UI ini di semua proyek Anda. Kedengarannya keren? Tentu saja, tetapi masih ada satu masalah - runtime.

Jika proyek Anda ditulis dalam Angular (~ 500Kb), dan Anda memutuskan untuk menulis UI-kit di Bereaksi (~ 98Kb), kemudian seret di setiap proyek pada satu kerangka kerja, kerangka kerja lain, dan bahkan dengan sekelompok dependensi, kit UI itu sendiri langsung katakanlah itu tidak terlihat optimal.

Solusi


Untuk membantu kami menggunakan kerangka kerja yang sangat "menghilang", tanpa runtime. Kondisi utama di sini adalah bahwa mereka terisolasi mungkin dalam hal ekosistem mereka dan memiliki mekanisme integrasi eksternal dan API yang sesuai.

Sebuah contoh yang bagus dari kerangka kerja seperti itu adalah SvelteJS, tentang yang beberapa artikel telah ditulis di Habré .

Jadi, bayangkan situasi yang kita punya aplikasi pada Bereaksi. Mungkin kita sudah bosan, dan kita ingin menyingkirkannya, tetapi menulis ulang semuanya sekaligus adalah kemewahan yang tidak dapat diterima. Atau mungkin beberapa bagian aplikasi memerlukan perbaikan atau refactoring. Baik, atau kami memutuskan untuk membuat pustaka komponen tunggal, dan sekarang kami akan menulis semua komponen di Svelte dan digunakan dalam semua proyek. Disajikan? Ya, tentu saja tidak, tidak ada yang punya fantasi seperti itu. Mari kita lihat contoh nyata.


Penafian
Segera saya ingin menarik perhatian Anda pada fakta bahwa saya bukan pengembang Bereaksi dan terakhir kali saya "merasa" Bereaksi kembali pada tahun 2015. Oleh karena itu, saya mengira bahwa cara saya menulis bagian dari contoh Bereaksi dapat melukai perasaan reaksioner yang percaya . Saya minta maaf untuk tidak menghakimi secara ketat, terutama karena makna artikel tidak berubah dari ini.


Jadi, tugasnya adalah mengimplementasikan komponen Svelte yang sudah jadi ke dalam aplikasi Bereaksi, tanpa mengubah komponen itu sendiri dan tanpa membungkus runtime tambahan ke dalam aplikasi. Sebagai contoh, saya akan mengambil komponen yang mencari pengguna GitHub, yang saya tulis untuk artikel sebelumnya "Cara mencari pengguna di GitHub tanpa React + RxJS 6 + Komposisi Ulang" .

Kode untuk komponen ini dapat dilihat di REPL , dan kode sampel dari artikel ini ke repositori .

Buat aplikasi reaksi


Pertama, buat proyek Bereaksi baru menggunakan alat standar de facto - create-react-app :

npx create-react-app my-app cd my-app npm start 

Ok, jika Anda pergi ke port 3000, sepertinya berfungsi.

Sesuaikan Svelte


Jika Anda tidak tahu apa-apa tentang Svelte, maka saya akan mengatakan ini, dalam konteks tugas Svelte, ini hanya satu langkah lagi dari kolektor Anda (webpack / rollup / gupl / grunt / etc), yang akan memungkinkan Anda untuk menulis komponen dalam format SFC dan mengompilasinya dalam vanilla javascript.

Di komunitas Svelte, Rollup lebih disukai, yang tidak mengejutkan, karena mereka memiliki satu penulis - Rich Harris. Namun, karena CRA menggunakan webpack, kami akan mengonfigurasi Svelte melaluinya. Untuk melakukan ini, pertama-tama Anda perlu mentransfer konfigurasi webpack dari skrip reaksi ke proyek sehingga kami dapat mengubahnya. Ini dilakukan dengan menggunakan perintah bawaan:

 npm run eject 


Sejauh yang saya tahu, ini bukan pendekatan halal, tetapi misalnya ini adalah pilihan yang paling nyaman.

Sekarang konfigurasi webpack berada di root proyek, Anda dapat menginstal Svelte:

 npm i --save-dev svelte svelte-loader 


Perhatikan flag --save-dev , ingat ya, tidak ada runtime.))))

Sentuhan terakhir, Anda harus menghubungkan loader yang sesuai di konfigurasi:

  { test: /\.svelte$/, use: { loader: 'svelte-loader', } }, 


Secara umum, sudah biasa di komunitas Svelte untuk menulis file komponen dengan ekstensi .html , karena komponen Svelte adalah file HTML yang valid. Namun, untuk menghindari kemungkinan tabrakan, dalam beberapa kasus, lebih baik menggunakan format file .svelte khusus.

Jadi kami lakukan, sekarang semua file .svelte yang termasuk dalam proyek akan dicegat oleh loader ini dan dikompilasi oleh Svelte.

Menulis Komponen Langsing


Pertama, lebih baik untuk mengkonfigurasi editor kode, misalnya, sehingga menerapkan penyorotan sintaks html ke file dengan ekstensi yang sesuai. Sesuatu seperti ini dilakukan dalam Kode VS:

  "files.associations": { "*.svelte": "html" } 

Sekarang buat folder ./src/svelte_components/ dan di sana folder komponen itu sendiri. Setelah itu, kita cukup mentransfer semua file dari contoh REPL ke folder ini, secara bersamaan memberi mereka ekstensi .svelte baru , dan memanggil file App.html Widget.svelte.

Hasilnya harus seperti ini:


Di tempat yang sama kita membuat file index.js di mana kita akan memiliki kode integrasi Svelte dan React.

Integrasikan


Mungkin sekarang Anda ingin tahu apa itu sihir? Keajaibannya adalah kita telah melakukan semua keajaiban. Ajaib, bukan?

Serius, sekarang kita dapat menggunakan komponen Svelte dalam aplikasi Bereaksi kita sebagai konstruktor JS yang benar-benar biasa, yang berarti bahwa kode integrasi dengan Svelte tidak akan berbeda dengan integrasi dengan standalone lainnya. Dokumentasi React bahkan berisi bagian yang didedikasikan untuk ini: Integrasi dengan Perpustakaan Lain .

Kode integrasi mungkin terlihat seperti ini:

 import React, { PureComponent } from 'react'; import Widget from './Widget.svelte'; export default class extends PureComponent { componentDidMount() { const { username } = this.props; this.widget = new Widget({ target: this.el, data: { username } }); } componentWillUnmount() { this.widget.destroy(); } render() { return ( <div ref={el => this.el = el}></div> ); } } 

Secara total, kami hanya membungkus kode komponen Svelte kami yang kompleks dalam komponen Bereaksi yang sangat sederhana, yang hanya membuat contoh baru dari komponen Svelte, mentransfer elemen pemasangan dan data dari alat peraga saat membuatnya. Selain itu, kami tidak lupa untuk menghapus komponen Svelte di pengait komponenWillUnmount .

Satu-satunya hal yang belum kami lakukan adalah mereka tidak menyinkronkan nilai status komponen. Yaitu, jika komponen induk melemparkan alat peraga lain ke dalam komponen pembungkus, maka mereka harus berlaku untuk komponen Svelte. Sebaliknya, jika data telah diubah di dalam komponen Svelte, itu harus diputar kembali.

Untuk melakukan ini, kita mengasumsikan bahwa komponen Bereaksi tingkat lebih tinggi akan mengirimkan panggilan balik onChange, yang harus kita tarik ketika perubahan terjadi di dalam, dan kita akan mengharapkan perubahan dalam alat peraga komponen pembungkus dalam komponenWillReceiveProps hook. Mari kita lakukan:

  componentDidMount() { ... this.widget.on('state', ({ current: { username }, changed }) => { if (changed.username) { this.props.onChange({ username }); } }); } componentWillReceiveProps({ username }) { this.widget.set({ username }); } 

Di sini kami menggunakan keadaan bawaan, yang menyala setiap kali keadaan komponen Svelte berubah. Objek yang berisi status komponen saat ini ( saat ini ), keadaan sebelumnya ( sebelumnya ) dan daftar properti yang diubah ( diubah ) ditransfer ke callback. Karenanya, kami cukup memeriksa apakah nama pengguna telah diubah dan memanggil panggilan balik onChange, jika demikian.

Di kait komponenWillReceiveProps , kami menetapkan nama pengguna baru menggunakan metode bawaan () .

Selain bawaan, komponen Svelte dapat mengimplementasikan acara dan metode khusus. Ini adalah fitur-fitur bagus yang memungkinkan Anda untuk mendeskripsikan antarmuka komponen dan cukup nyaman untuk mengatur komunikasi dengan "dunia luar".

Gunakan


Sekarang mari kita coba gunakan widget kita secara langsung di aplikasi Bereaksi. Untuk melakukan ini, edit file App.js yang dihasilkan oleh starter:

 import React, { Component } from 'react'; import './App.css'; import GithubWidget from './svelte_components/GithubWidget'; class App extends Component { constructor() { super(); this.state = { username: '' }; } handleChange = (state) => { this.setState({ ...state }); } render() { return ( <div className="App"> <header className="App-header"> <h1>Github Widget for: {this.state.username}</h1> <GithubWidget onChange={this.handleChange} username={this.state.username} /> </header> </div> ); } } export default App; 

Singkatnya, kami menggunakannya sebagai komponen Bereaksi biasa. Dan sebagai hasilnya kita dapatkan:


Sudah tidak buruk, kan?) Harap dicatat bahwa nilai nama pengguna yang kami masukkan di bidang teks widget segera diteruskan ke aplikasi Bereaksi.

Kami akan menyelesaikan


Mari sekarang ajarkan widget kami untuk mencari dan menampilkan tidak hanya kartu pengguna GitHub, tetapi juga kartu repositori.

Pertama, Anda perlu membuat Repo.svelte komponen baru, yang akan menarik kartu repositori. Untuk mempermudah, saya hanya menyalin templat dan gaya dari User.svelte dan menyesuaikannya dengan data repositori. Namun, secara teori ini adalah komponen yang terpisah.

Selanjutnya, Anda perlu mengajarkan komponen kontrol Widget.svelte untuk mengganti kedua jenis kartu ini dengan cepat. Selain itu, Anda perlu mengajarinya untuk menarik berbagai permintaan untuk pengguna dan repositori.

Kami akan menggunakan satu bidang untuk input dan menentukan tipe data dengan adanya "/" dalam nilai. Artinya, jika Anda perlu mencari pengguna, masukkan nama pengguna, dan jika repositori, lalu masukkan nama pengguna pengguna, lalu "/" dan nama repositori.

Pada pandangan pertama, ini terlihat agak membingungkan, tetapi pada Svelte solusinya akan mengambil secara harfiah 5-6 baris kode. Pertama, mari sambungkan komponen baru dan metode API, yang kami bungkus dalam debounce:

 ... import Repo from './Repo.svelte'; ... import { getUserCard, getRepoCard } from './api.js'; ... const getRepo = debounce(getRepoCard, 1000); 

Selanjutnya, buat properti yang dihitung yang akan menentukan jenis kartu yang harus kami perlihatkan:

 computed: { ... repo: ({ username }) => username.includes('/'), ... } 

Sekarang tambahkan saklar permintaan ke API:

 computed: { ... card: ({ username, repo }) => username && (repo ? getRepo : getUser)(username), ... } 

Dan akhirnya, mengganti komponen kartu tergantung pada jenisnya:

 computed: { ... Card: ({ repo }) => repo ? Repo : User, ... } 

Selain itu, untuk mengganti komponen secara dinamis, kita perlu menggunakan tag Svelte khusus, yang menarik komponen yang nilainya diteruskan ke atribut ini :

 <svelte:component this={Card} {...card} /> 


Itu bekerja. Pernahkah Anda memperhatikan? Kami sudah menulis di Svelte di dalam aplikasi Bereaksi! )))

Sekarang mari kita ajarkan widget kita untuk menyembunyikan kolom input dan mencoba memasukkan nama pengguna yang bukan di dalam widget, tetapi di dalam aplikasi Bereaksi. Apakah penting bagaimana logika bisnis kita akan mendapatkan nilai ini.

Kami memperkenalkan properti pencarian baru yang nilai defaultnya salah. Bergantung pada properti ini, bidang input akan ditampilkan atau tidak ditampilkan. Secara default, karenanya, tidak akan ada bidang.

 {#if search} <input bind:value=username placeholder="username or username/repo"> {/if} ... <script> export default { ... data() { return { username: '', search: false }; }, ... }; </script> 

Sekarang di App.js kita akan membuat bidang input di sisi Bereaksi dari aplikasi dan menulis pemrosesan yang sesuai untuk acara input:

  ... handleUsername = (e) => { this.setState({ username: e.target.value }); } ... <h1>Github Widget for: {this.state.username}</h1> <input value={this.state.username} onChange={this.handleUsername} className="Username" placeholder="username or username/repo" /> 

Dan juga salin ke folder dengan widget di sini adalah seperti svg spinner di Svelte:

 <svg height={size} width={size} style="animation-duration:{speed}ms;" class="svelte-spinner" viewbox="0 0 32 32" > <circle role="presentation" cx="16" cy="16" r={radius} stroke={color} fill="none" stroke-width={thickness} stroke-dasharray="{dash},100" stroke-linecap="round" /> </svg> <script> export default { data() { return { size: 25, speed: 750, color: 'rgba(0,0,0,0.4)', thickness: 2, gap: 40, radius: 10 }; }, computed: { dash: ({radius, gap}) => 2 * Math.PI * radius * (100 - gap) / 100 } }; </script> <style> .svelte-spinner { transition-property: transform; animation-name: svelte-spinner_infinite-spin; animation-iteration-count: infinite; animation-timing-function: linear; } @keyframes svelte-spinner_infinite-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } </style> 

Dan kami akan menerapkannya di widget sehingga sangat indah:

 ... {#await card} <Spinner size="50" speed="750" color="#38b0ee" thickness="2" gap="40" /> {:then card} ... 

Menurut pendapat saya, ternyata tidak terlalu buruk:


Topi paling atas dengan latar belakang hitam dan bidang input adalah aplikasi Bereaksi, blok putih di bawahnya adalah widget Svelte. Ini adalah pai. )))

Repositori

Kesimpulan


Svelte adalah alat yang hebat untuk mengembangkan aplikasi web berbasis komponen modern. Selain itu, Anda dapat dengan cepat dan mudah menulis komponen dan widget UI mandiri yang dapat digunakan kembali, yang dapat digunakan dalam aplikasi web apa pun, bahkan dalam hubungannya dengan kerangka kerja lain. Ini juga bagus untuk mikrofront .

Svelte sangat cocok untuk Anda jika:


  1. Anda ingin memulai proyek baru dan tidak tahu kerangka kerja mana yang harus dipilih untuk ini.
  2. Anda memiliki proyek, itu berfungsi dan lebih baik tidak menyentuhnya. Komponen dan modul baru, Anda dapat menulis dalam Svelte dan berintegrasi mulus ke dalam kode yang ada.
  3. Anda sudah memiliki proyek, tetapi sebagian atau seluruhnya sudah usang dan / atau memerlukan refactoring serius, hingga penulisan ulang lengkap. Anda dapat mulai menulis ulang dalam beberapa bagian. Dalam hal ini, Anda tidak perlu membuat konfigurasi yang rumit. Anda hanya mengambil beberapa komponen, menulis ulang ke Svelte dan bungkus komponen baru dengan yang lama. Namun, sisa aplikasi bahkan tidak menyadari perubahannya.
  4. Anda memiliki beberapa proyek pada basis kode yang berbeda dan pada saat yang sama, Anda ingin memiliki satu kit UI dan menggunakannya di salah satu proyek ini. Tulis kit-UI pada Svelte dan gunakan di mana saja. Ini bagus

Ingin mengetahui lebih banyak kasus menarik? Bergabunglah dengan saluran Telegram kami!

PEMBARUAN: terima kasih justboris untuk pertanyaan yang benar. Melanjutkan contoh:

 import React, { PureComponent } from 'react'; import Widget from './Widget.svelte'; export default class extends PureComponent { componentDidMount() { ... this.widget = new Widget({ target: this.el, data: { username }, slots: { default: this.slot } }); ... } ... render() { return ( <div ref={el => this.el = el}> <div ref={el => this.slot = el}> {this.props.children} </div> </div> ); } } 


 <GithubWidget onChange={this.handleChange} username={this.state.username}> <p>Hello world</p> </GithubWidget> 

Source: https://habr.com/ru/post/id420113/


All Articles