Membangun SSG yang Selalu Saya Inginkan: Sandwich 11ty, Vite, dan JAM

Diterbitkan: 2022-03-10
Ringkasan singkat Kembali pada Januari 2020, Ben Holmes mulai melakukan apa yang hampir dilakukan setiap pengembang web setiap tahun: membangun kembali situs pribadinya. Dalam artikel ini, dia membagikan kisahnya tentang bagaimana dia mulai membangun pipa build-nya sendiri dari titik nol mutlak dan menciptakan Slinkity.

Saya tidak tahu tentang Anda, tetapi saya kewalahan dengan semua alat pengembangan web yang kami miliki akhir-akhir ini. Baik Anda menyukai Markdown, HTML biasa, React, Vue, Svelte, Pug templates, Handlebars, Vibranium — Anda mungkin dapat menggabungkannya dengan beberapa data CMS dan mendapatkan koktail situs statis yang bagus.

Saya tidak akan memberi tahu Anda alat pengembangan UI mana yang harus dijangkau karena semuanya hebat — tergantung pada kebutuhan proyek Anda. Posting ini adalah tentang menemukan generator situs statis yang sempurna untuk setiap kesempatan; sesuatu yang memungkinkan kita menggunakan template tanpa JS seperti penurunan harga untuk memulai, dan membawa "pulau" interaktivitas berbasis komponen sesuai kebutuhan.

Saya menyaring pembelajaran selama satu tahun menjadi satu posting di sini. Kita tidak hanya akan membicarakan kode (alias lakban 11ty dan Vite bersama-sama), tetapi kita juga akan mengeksplorasi mengapa pendekatan ini begitu universal untuk masalah Jamstackian. Kami akan menyentuh:

  • Dua pendekatan untuk pembuatan situs statis, dan mengapa kita harus menjembatani kesenjangan;
  • Di mana bahasa templating seperti Pug dan Nunjucks masih terbukti bermanfaat;
  • Ketika kerangka kerja komponen seperti React atau Svelte harus ikut bermain;
  • Bagaimana dunia Vite yang baru dan hot-reload membantu kami menghadirkan interaktivitas JS ke HTML kami dengan hampir nol konfigurasi;
  • Bagaimana ini melengkapi kaskade data 11ty, membawa data CMS ke kerangka komponen atau template HTML apa pun yang Anda inginkan.

Jadi tanpa basa-basi lagi, inilah kisah saya tentang skrip build yang mengerikan, terobosan bundler, dan lakban kode-spageti yang (akhirnya) memberi saya SSG yang selalu saya inginkan: sandwich 11ty, Vite, dan Jam yang disebut Slinkity!

Pembagian Besar Dalam Pembuatan Situs Statis

Sebelum menyelam, saya ingin membahas apa yang saya sebut dua "kubu" dalam pembuatan situs statis.

Di kamp pertama, kami memiliki generator situs statis "sederhana". Alat ini tidak menghadirkan bundel JavaScript, aplikasi satu halaman, dan kata kunci lainnya yang kami harapkan. Mereka hanya menguasai dasar-dasar Jamstack: tarik data dari gumpalan JSON CMS mana pun yang Anda inginkan, dan geser data itu ke dalam template HTML biasa + CSS. Alat seperti Jekyll, Hugo, dan 11ty mendominasi kamp ini, memungkinkan Anda mengubah direktori penurunan harga dan file cair menjadi situs web yang berfungsi penuh. Kunci Keuntungan:

  • Kurva belajar yang dangkal
    Jika Anda tahu HTML, Anda siap melakukannya!
  • Waktu pembuatan yang cepat
    Kami tidak memproses sesuatu yang rumit, jadi setiap rute dibuat dalam sekejap.
  • Waktu instan untuk interaktif
    Tidak ada (atau sangat sedikit) JavaScript untuk diurai di klien.

Sekarang di kamp kedua, kami memiliki generator situs statis "dinamis". Ini memperkenalkan kerangka kerja komponen seperti React, Vue, dan Svelte untuk menghadirkan interaktivitas ke Jamstack Anda. Ini memenuhi janji inti yang sama dalam menggabungkan data CMS dengan rute situs Anda pada waktu pembuatan. Kunci Keuntungan:

  • Dibuat untuk interaktivitas
    Butuh carousel gambar animasi? Formulir multi-langkah? Cukup tambahkan nugget komponen HTML, CSS, dan JS.
  • manajemen negara
    Sesuatu seperti React Context of Svelte store memungkinkan berbagi data tanpa batas antar rute. Misalnya, keranjang di situs e-niaga Anda.

Ada pro yang berbeda untuk kedua pendekatan. Tetapi bagaimana jika Anda memilih SSG dari kamp pertama seperti Jekyll, hanya untuk menyadari enam bulan dalam proyek Anda bahwa Anda memerlukan beberapa interaktivitas komponen-y? Atau Anda memilih sesuatu seperti NextJS untuk komponen yang kuat itu, hanya untuk berjuang dengan kurva belajar React, atau KB JavaScript yang tidak perlu pada posting blog statis?

Beberapa proyek benar -benar cocok dengan satu kubu atau yang lain menurut saya. Mereka ada pada spektrum, terus-menerus mendukung set fitur baru saat kebutuhan proyek berkembang. Jadi bagaimana kita menemukan solusi yang memungkinkan kita memulai dengan alat sederhana dari kamp pertama, dan secara bertahap menambahkan fitur dari yang kedua saat kita membutuhkannya?

Baiklah, mari kita telusuri perjalanan belajar saya sebentar.

Catatan: Jika Anda sudah menjual templat statis dengan 11ty untuk membangun situs statis Anda, silakan kunjungi panduan kode menarik.

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

Beralih Dari Komponen Ke Template Dan Web API

Kembali pada Januari 2020, saya mulai melakukan apa yang hampir setiap pengembang web lakukan setiap tahun: membangun kembali situs pribadi saya. Tapi kali ini akan berbeda. Saya menantang diri saya sendiri untuk membangun situs dengan tangan terikat di belakang, tidak ada kerangka kerja atau saluran pipa yang diizinkan!

Ini bukan tugas sederhana sebagai pemuja React. Tetapi dengan kepala tegak, saya mulai membangun pipa bangunan saya sendiri dari titik nol mutlak. Ada banyak kode yang ditulis dengan buruk yang dapat saya bagikan dari v1 situs pribadi saya… tetapi saya akan membiarkan Anda mengklik README ini jika Anda begitu berani. Sebaliknya, saya ingin fokus pada takeaways tingkat yang lebih tinggi yang saya pelajari membuat diri saya kelaparan akan kesenangan bersalah JS saya.

Template Lebih Jauh Dari yang Anda Pikirkan

Saya datang di proyek ini sebagai pecandu JavaScript yang pulih. Ada beberapa kebutuhan terkait situs statis yang saya sukai menggunakan kerangka kerja berbasis komponen untuk diisi:

  1. Kami ingin memecah situs saya menjadi komponen UI yang dapat digunakan kembali yang dapat menerima objek JS sebagai parameter (alias "alat peraga").
  2. Kami perlu mengambil beberapa informasi pada waktu pembuatan untuk diterapkan ke situs produksi.
  3. Kita perlu menghasilkan banyak rute URL dari direktori file atau objek konten JSON yang gemuk.

Daftar diambil dari posting ini di blog pribadi saya.

Tetapi Anda mungkin telah memperhatikan… tidak satu pun dari ini yang benar- benar membutuhkan JavaScript sisi klien. Kerangka kerja komponen seperti React terutama dibuat untuk menangani masalah manajemen keadaan, seperti aplikasi web Facebook yang menginspirasi React. Jika Anda baru saja memecah situs Anda menjadi komponen berukuran kecil atau elemen sistem desain, template seperti Pug juga berfungsi dengan baik!

Ambil bilah navigasi ini misalnya. Di Pug, kita dapat mendefinisikan "mixin" yang menerima data sebagai alat peraga:

 // nav-mixins.pug mixin NavBar(links) // pug's version of a for loop each link in links a(href=link.href) link.text

Kemudian, kita dapat menerapkan mixin itu di mana saja di situs kita.

 // index.pug // kinda like an ESM "import" include nav-mixins.pug html body +NavBar(navLinksPassedByJS) main h1 Welcome to my pug playground

Jika kita "merender" file ini dengan beberapa data, kita akan mendapatkan index.html yang indah untuk disajikan kepada pengguna kita.

 const html = pug.render('/index.pug', { navLinksPassedByJS: [ { href: '/', text: 'Home' }, { href: '/adopt', text: 'Adopt a Pug' } ] }) // use the NodeJS filesystem helpers to write a file to our build await writeFile('build/index.html', html)

Tentu, ini tidak memberikan basa-basi seperti CSS lingkup untuk mixin Anda, atau JavaScript stateful di tempat yang Anda inginkan. Tetapi ia memiliki beberapa manfaat yang sangat kuat dibandingkan sesuatu seperti Bereaksi:

  1. Kami tidak membutuhkan bundler mewah yang tidak kami mengerti.
    Kami baru saja menulis panggilan pug.render itu dengan tangan, dan kami sudah memiliki rute pertama situs yang siap digunakan.
  2. Kami tidak mengirimkan JavaScript apa pun ke pengguna akhir.
    Menggunakan React sering kali berarti mengirimkan runtime ole besar untuk dijalankan oleh browser orang. Dengan memanggil fungsi seperti pug.render pada waktu pembuatan, kami menyimpan semua JS di pihak kami saat mengirim file .html bersih di akhir.

Inilah mengapa saya pikir template adalah "dasar" yang bagus untuk situs statis. Namun, dapat menjangkau kerangka kerja komponen di mana kita benar -benar mendapat manfaat darinya akan menyenangkan. Lebih lanjut tentang itu nanti.

Bacaan yang Direkomendasikan : Cara Membuat Template Sudut Lebih Baik Dengan Pug oleh Zara Cooper

Anda Tidak Perlu Kerangka Kerja Untuk Membuat Aplikasi Satu Halaman

Sementara saya melakukannya, saya juga menginginkan beberapa transisi halaman seksi di situs saya. Tapi bagaimana kita melakukan sesuatu seperti ini tanpa kerangka kerja?

Crossfade dengan transisi penghapusan vertikal
Crossfade dengan transisi wipe vertikal. (Pratinjau besar)

Kami tidak dapat melakukan ini jika setiap halaman memiliki file .html sendiri. Seluruh browser di-refresh ketika kita melompat dari satu file HTML ke file HTML lainnya, jadi kita tidak dapat memiliki efek cross-fade yang bagus (karena kita akan secara singkat menampilkan kedua halaman di atas satu sama lain).

Kami membutuhkan cara untuk "mengambil" HTML dan CSS ke mana pun kami menavigasi, dan menganimasikannya ke tampilan menggunakan JavaScript. Ini terdengar seperti pekerjaan untuk aplikasi satu halaman! Saya menggunakan medley API browser sederhana untuk ini:

  1. Cegat semua klik tautan Anda menggunakan pendengar acara.
  2. fetch API : Ambil semua sumber daya untuk halaman apa pun yang ingin Anda kunjungi, dan ambil bagian yang ingin saya animasikan agar terlihat: konten di luar navbar (yang saya ingin tetap diam selama animasi).
  3. web animations API : Menganimasikan konten baru ke tampilan sebagai bingkai utama.
  4. history API : Ubah tampilan rute di bilah URL browser Anda menggunakan window.history.pushState({}, 'new-route') . Jika tidak, sepertinya Anda tidak pernah meninggalkan halaman sebelumnya!

Untuk kejelasan, berikut adalah ilustrasi visual dari konsep aplikasi satu halaman menggunakan pencarian dan penggantian sederhana ( artikel sumber ):

Proses perutean sisi klien selangkah demi selangkah: 1. Hamburger langka sedang dikembalikan, 2. Kami meminta burger matang menggunakan API fetch, 3. Kami memijat respons, 4. Kami mencabut elemen 'patty' dan menerapkannya ke halaman kami saat ini.
Proses perutean sisi klien selangkah demi selangkah: 1. Hamburger langka sedang dikembalikan, 2. Kami meminta burger matang menggunakan API fetch, 3. Kami memijat respons, 4. Kami mencabut elemen 'patty' dan menerapkannya ke halaman kami saat ini. (Pratinjau besar)

Catatan : Anda juga dapat mengunjungi kode sumber dari situs pribadi saya.

Tentu, beberapa pasangan React et al dan perpustakaan animasi pilihan Anda dapat melakukan ini. Tetapi untuk kasus penggunaan yang sederhana seperti transisi fade… API web cukup kuat dengan sendirinya. Dan jika Anda ingin transisi halaman yang lebih kuat pada template statis seperti Pug atau HTML biasa, perpustakaan seperti Swap akan melayani Anda dengan baik.

Apa yang Dibawa ke Meja?

Saya merasa cukup baik tentang SSG kecil saya pada saat ini. Tentu saja itu tidak dapat mengambil data CMS apa pun pada waktu pembuatan, dan tidak mendukung tata letak yang berbeda berdasarkan halaman atau direktori, dan tidak mengoptimalkan gambar saya, dan tidak memiliki versi tambahan.

Oke, saya mungkin butuh bantuan.

Mengingat semua pembelajaran saya dari v1, saya pikir saya mendapatkan hak saya untuk membatalkan aturan "tidak ada saluran pipa pembangunan pihak ketiga" dan menjangkau alat yang ada. Ternyata, 11ty memiliki banyak fitur yang saya butuhkan!

  • Pengambilan data pada waktu pembuatan menggunakan file .11ydata.js ;
  • Data global tersedia untuk semua template saya dari folder _data ;
  • Reload panas selama pengembangan menggunakan browsersync;
  • Dukungan untuk transformasi HTML mewah;
  • …dan barang-barang lainnya yang tak terhitung jumlahnya.

Jika Anda sudah mencoba SSG sederhana seperti Jekyll atau Hugo, Anda seharusnya sudah memiliki gambaran yang cukup bagus tentang cara kerja 11ty. Hanya perbedaan? 11ty menggunakan JavaScript terus-menerus.

11ty pada dasarnya mendukung setiap perpustakaan template di luar sana, jadi dengan senang hati merender semua halaman Pug saya ke rute .html . Opsi rantai tata letak ini membantu dengan pengaturan aplikasi satu halaman palsu saya juga. Saya hanya membutuhkan satu script untuk semua rute saya, dan tata letak "global" untuk mengimpor skrip itu:

 // _includes/base-layout.html <html> <body> <!--load every page's content between some body tags--> {{ content }} <!--and apply the script tag just below this--> <script src="main.js"></script> </body> </html> // random-blog-post.pug --- layout: base-layout --- article h2 Welcome to my blog p Have you heard the story of Darth Plagueis the Wise?

Selama main.js itu melakukan semua penyadapan tautan yang kami jelajahi, kami memiliki transisi halaman!

Oh, Dan Kaskade Data

Jadi 11ty membantu membersihkan semua kode spaghetti saya dari v1. Tapi itu membawa bagian penting lainnya: API bersih untuk memuat data ke dalam tata letak saya. Ini adalah roti dan mentega dari pendekatan Jamstack. Alih-alih mengambil data di browser dengan manipulasi JavaScript + DOM, Anda dapat:

  1. Ambil data pada waktu build menggunakan Node.js.
    Ini bisa berupa panggilan ke beberapa API eksternal, impor JSON atau YAML lokal, atau bahkan konten rute lain di situs Anda (bayangkan memperbarui daftar isi setiap kali rute baru ditambahkan ).
  2. Masukkan data itu ke dalam rute Anda. Ingat fungsi .render yang kita tulis sebelumnya:
 const html = pug.render('/index.pug', { navLinksPassedByJS: [ { href: '/', text: 'Home' }, { href: '/adopt', text: 'Adopt a Pug' } ] })

…tetapi alih-alih memanggil pug.render dengan data kami setiap saat, kami membiarkan 11ty melakukan ini di belakang layar.

Tentu, saya tidak memiliki banyak data untuk situs pribadi saya. Tapi rasanya luar biasa untuk menyiapkan file .yaml untuk semua proyek pribadi saya:

 # _data/works.yaml - title: Bits of Good Homepage hash: bog-homepage links: - href: https://bitsofgood.org text: Explore the live site - href: https://github.com/GTBitsOfGood/bog-web text: Scour the Svelt-ified codebase timeframe: May 2019 - present tags: - JAMstack - SvelteJS - title: Dolphin Audio Visualizer ...

Dan akses data itu di semua template:

 // home.pug .project-carousel each work in works h3 #{title} p #{timeframe} each tag in tags ...

Berasal dari dunia "rendering sisi klien" dengan aplikasi create-react-app, ini adalah wahyu yang cukup besar. Tidak perlu lagi mengirim kunci API atau gumpalan JSON besar ke browser.

Saya juga menambahkan beberapa barang untuk pengambilan JavaScript dan peningkatan animasi pada versi 1 situs saya. Jika Anda penasaran, di sinilah README saya berdiri saat ini.

Saya Senang Pada Saat Ini Tetapi Ada Sesuatu yang Hilang

Saya melangkah jauh dengan meninggalkan komponen berbasis JS dan menggunakan template (dengan transisi halaman animasi untuk boot). Tapi saya tahu ini tidak akan memuaskan kebutuhan saya selamanya. Ingat perpecahan besar yang saya alami? Yah, jelas masih ada jurang antara pengaturan build saya (dengan kuat di kamp #1) dan surga interaktivitas JS-ified (Next, SvelteKit, dan lebih banyak lagi dari kamp #2). Katakanlah saya ingin menambahkan:

  • modal pop-up dengan sakelar buka/tutup,
  • sistem desain berbasis komponen seperti UI Material, lengkap dengan gaya tercakup,
  • bentuk multi-langkah yang kompleks, mungkin didorong oleh mesin negara.

Jika Anda seorang murni-JS-murni, Anda mungkin memiliki jawaban tanpa kerangka kerja untuk semua kasus penggunaan tersebut. Tapi ada alasan mengapa JQuery bukan lagi norma! Ada sesuatu yang menarik tentang membuat komponen HTML yang terpisah dan mudah dibaca, gaya tercakup, dan potongan variabel "status" JavaScript. React, Vue, Svelte, dll. menawarkan begitu banyak kebaikan untuk debugging dan pengujian sehingga manipulasi DOM langsung tidak dapat dicocokkan.

Jadi, inilah pertanyaan jutaan dolar saya:

Bisakah kita menggunakan template HTML langsung untuk memulai, dan secara bertahap menambahkan komponen React/Vue/Svelte di tempat yang kita inginkan?

Jawabannya adalah ya . Mari kita coba.

11ty + Vite: Pertandingan yang Dibuat Di Surga ️

Inilah mimpi yang saya bayangkan di sini. Di mana pun saya ingin menyisipkan sesuatu yang interaktif, saya ingin meninggalkan sedikit tanda di template saya untuk “meletakkan komponen X React di sini.” Ini bisa berupa sintaks kode pendek yang didukung 11ty:

 # Super interesting programming tutorial Writing paragraphs has been fun, but that's no way to learn. Time for an interactive code example! {% react './components/FancyLiveDemo.jsx' %}

Tapi ingat, one-piece 11ty (sengaja) menghindari: cara untuk menggabungkan semua JavaScript Anda. Berasal dari serikat bundling OG, otak Anda mungkin melompat untuk membangun proses Webpack, Rollup, atau Babel di sini. Buat file titik masuk ole besar, dan hasilkan beberapa kode yang dioptimalkan dengan indah, bukan?

Ya, tapi ini bisa sangat terlibat. Jika kita menggunakan komponen React, misalnya, kita mungkin memerlukan beberapa loader untuk JSX, proses Babel yang bagus untuk mengubah segalanya, penerjemah untuk impor modul SASS dan CSS, sesuatu untuk membantu memuat ulang secara langsung, dan seterusnya.

Kalau saja ada alat yang bisa melihat file .jsx kami dan tahu persis apa yang harus dilakukan dengannya.

Masukkan: Vite

Vite telah menjadi pembicaraan di kota akhir-akhir ini. Ini dimaksudkan untuk menjadi alat all-in-one untuk membangun apa saja di JavaScript. Berikut contohnya untuk Anda coba di rumah. Mari buat direktori kosong di suatu tempat di mesin kita dan instal beberapa dependensi:

 npm init -y # Make a new package.json with defaults set npm i vite react react-dom # Grab Vite + some dependencies to use React

Sekarang, kita dapat membuat file index.html untuk berfungsi sebagai "titik masuk" aplikasi kita. Kami akan membuatnya cukup sederhana:

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <h1>Hello Vite! (wait is it pronounced "veet" or "vight"...)</h1> <div></div> </body> </html>

Satu-satunya hal yang menarik adalah div id="root" di tengah. Ini akan menjadi akar dari komponen React kita sebentar lagi!

Jika mau, Anda dapat menjalankan server Vite untuk melihat file HTML biasa kami di browser Anda. Jalankan saja vite (atau npx vite jika perintah tidak dikonfigurasi di terminal Anda), dan Anda akan melihat hasil yang berguna ini:

 vite vX.XX dev server running at: > Local: http://localhost:3000/ > Network: use `--host` to expose ready in Xms.

Sama seperti Browsersync atau server dev populer lainnya, nama setiap file .html sesuai dengan rute di server kami. Jadi jika kami mengganti nama index.html menjadi about.html , kami akan mengunjungi http://localhost:3000/about/ (ya, Anda memerlukan garis miring!)

Sekarang mari kita lakukan sesuatu yang menarik. Di samping file index.html itu, tambahkan semacam komponen React dasar. Kami akan menggunakan useState React di sini untuk mendemonstrasikan interaktivitas:

 // TimesWeMispronouncedVite.jsx import React from 'react' export default function TimesWeMispronouncedVite() { const [count, setCount] = React.useState(0) return ( <div> <p>I've said Vite wrong {count} times today</p> <button onClick={() => setCount(count + 1)}>Add one</button> </div> ) }

Sekarang, mari muat komponen itu ke halaman kita. Ini semua yang harus kita tambahkan ke index.html kita :

 <!DOCTYPE html> ... <body> <h1>Hello Vite! (wait is it pronounced "veet" or "vight"...)</h1> <div></div> <!--Don't forget type="module"! This lets us use ES import syntax in the browser--> <script type="module"> // path to our component. Note we still use .jsx here! import Component from './TimesWeMispronouncedVite.jsx'; import React from 'react'; import ReactDOM from 'react-dom'; const componentRoot = document.getElementById('root'); ReactDOM.render(React.createElement(Component), componentRoot); </script> </body> </html>

Ya, itu saja. Tidak perlu mengubah file .jsx kita menjadi file .js yang siap-browser sendiri! Di mana pun Vite melihat impor .jsx , itu akan secara otomatis mengonversi file itu menjadi sesuatu yang dapat dipahami oleh browser. Bahkan tidak ada folder dist atau build saat bekerja dalam pengembangan; Vite memproses semuanya dengan cepat — lengkap dengan pemuatan ulang modul panas setiap kali kami menyimpan perubahan kami.

Oke, jadi kami memiliki alat pembuatan yang sangat mumpuni. Bagaimana kita bisa membawa ini ke template 11ty kita?

Menjalankan Vite Bersama 11ty

Sebelum kita beralih ke hal-hal yang baik, mari kita bahas menjalankan 11ty dan Vite secara berdampingan. Silakan dan instal 11ty sebagai ketergantungan dev ke direktori proyek yang sama dari bagian terakhir:

 npm i -D @11ty/eleventy # yes, it really is 11ty twice

Sekarang mari kita lakukan sedikit pemeriksaan pra-penerbangan untuk melihat apakah 11ty berfungsi. Untuk menghindari kebingungan, saya sarankan Anda:

  1. Hapus file index.html itu dari sebelumnya;
  2. Pindahkan TimesWeMispronouncedVite.jsx itu ke dalam direktori baru. Katakanlah, components/ ;
  3. Buat folder src untuk situs web kami;
  4. Tambahkan templat ke direktori src itu untuk diproses 11ty.

Misalnya, file blog-post.md dengan konten berikut:

 # Hello world! It's markdown here

Struktur proyek Anda akan terlihat seperti ini:

 src/ blog-post.md components/ TimesWeMispronouncedVite.jsx

Sekarang, jalankan 11ty dari terminal Anda seperti:

 npx eleventy --input=src

Jika semuanya berjalan dengan baik, Anda akan melihat output build seperti ini:

 _site/ blog-post/ index.html

Di mana _site adalah direktori keluaran default kami, dan blog-post/index.html adalah file penurunan harga kami yang dikonversi dengan indah untuk penjelajahan.

Biasanya, kami akan menjalankan npx eleventy --serve untuk menjalankan server dev dan mengunjungi halaman /blog-post . Tapi kami menggunakan Vite untuk server dev kami sekarang! Tujuannya di sini adalah untuk:

  1. Minta sebelas puluh membangun penurunan harga kami, Pug, nunjucks, dan lainnya ke direktori _site .
  2. Arahkan Vite ke direktori _site yang sama sehingga dapat memproses komponen React, impor gaya mewah, dan hal-hal lain yang tidak diambil oleh 11ty.

Jadi proses pembuatan dua langkah, dengan 11 puluh menyerahkan Vite. Inilah perintah CLI yang Anda perlukan untuk memulai 11ty dan Vite dalam mode "watch" secara bersamaan:

 (npx eleventy --input=src --watch) & npx vite _site

Anda juga dapat menjalankan perintah ini di dua terminal terpisah untuk memudahkan debugging.

Dengan sedikit keberuntungan, Anda seharusnya dapat mengunjungi http://localhost:3000/blog-post/ (sekali lagi, jangan lupa garis miring!) untuk melihat file penurunan harga yang diproses.

Hidrasi Parsial Dengan Kode Pendek

Mari kita lakukan ikhtisar singkat tentang kode pendek. Saatnya untuk meninjau kembali sintaks itu dari sebelumnya:

 {% react '/components/TimesWeMispronouncedVite.jsx' %}

Bagi mereka yang tidak terbiasa dengan kode pendek: mereka hampir sama dengan panggilan fungsi, di mana fungsi mengembalikan string HTML untuk meluncur ke halaman Anda. "Anatomi" kode pendek kami adalah:

  • {% … %}
    Wrapper yang menunjukkan awal dan akhir kode pendek.
  • react
    Nama fungsi kode pendek kami akan kami konfigurasikan sebentar lagi.
  • '/components/TimesWeMispronouncedVite.jsx'
    Argumen pertama (dan satu-satunya) untuk fungsi kode pendek kami. Anda dapat memiliki argumen sebanyak yang Anda inginkan.

Mari kita pasang kode pendek pertama kita! Tambahkan file .eleventy.js ke dasar proyek Anda, dan tambahkan entri konfigurasi ini untuk kode pendek react kami:

 // .eleventy.js, at the base of the project module.exports = function(eleventyConfig) { eleventyConfig.addShortcode('react', function(componentPath) { // return any valid HTML to insert return `<div>This is where we'll import ${componentPath}</div>` }) return { dir: { // so we don't have to write `--input=src` in our terminal every time! input: 'src', } } }

Sekarang, mari kita membumbui blog-post.md kita dengan shortcode baru kita. Tempel konten ini ke file penurunan harga kami:

 # Super interesting programming tutorial Writing paragraphs has been fun, but that's no way to learn. Time for an interactive code example! {% react '/components/TimesWeMispronouncedVite.jsx' %}

Dan jika Anda menjalankan npx eleventy cepat, Anda akan melihat output ini di direktori _site Anda di bawah /blog-post/index.html :

 <h1>Super interesting programming tutorial</h1> <p>Writing paragraphs has been fun, but that's no way to learn. Time for an interactive code example!</p> <div>This is where we'll import /components/TimesWeMispronouncedVite.jsx</div>

Menulis Kode Pendek Komponen Kami

Sekarang mari kita lakukan sesuatu yang berguna dengan kode pendek itu. Ingat tag script yang kami tulis saat mencoba Vite? Nah, kita bisa melakukan hal yang sama di shortcode kita! Kali ini kita akan menggunakan argumen componentPath untuk menghasilkan impor, tetapi sisanya tetap sama:

 // .eleventy.js module.exports = function(eleventyConfig) { let idCounter = 0; // copy all our /components to the output directory // so Vite can find them. Very important step! eleventyConfig.addPassthroughCopy('components') eleventyConfig.addShortcode('react', function (componentPath) { // we'll use idCounter to generate unique IDs for each "root" div // this lets us use multiple components / shortcodes on the same page idCounter += 1; const componentRootId = `component-root-${idCounter}` return ` <div></div> <script type="module"> // use JSON.stringify to // 1) wrap our componentPath in quotes // 2) strip any invalid characters. Probably a non-issue, but good to be cautious! import Component from ${JSON.stringify(componentPath)}; import React from 'react'; import ReactDOM from 'react-dom'; const componentRoot = document.getElementById('${componentRootId}'); ReactDOM.render(React.createElement(Component), componentRoot); </script> ` }) eleventyConfig.on('beforeBuild', function () { // reset the counter for each new build // otherwise, it'll count up higher and higher on every live reload idCounter = 0; }) return { dir: { input: 'src', } } }

Sekarang, panggilan ke kode pendek kami (mis. {% react '/components/TimesWeMispronouncedVite.jsx' %} ) akan menampilkan sesuatu seperti ini:

 <div></div> <script type="module"> import Component from './components/FancyLiveDemo.jsx'; import React from 'react'; import ReactDOM from 'react-dom'; const componentRoot = document.getElementById('component-root-1'); ReactDOM.render(React.createElement(Component), componentRoot); </script>

Mengunjungi server dev kami menggunakan (npx eleventy --watch) & vite _site , kami akan menemukan elemen penghitung yang dapat diklik dengan indah.

Buzzword Alert — Hidrasi Parsial Dan Arsitektur Kepulauan

Kami baru saja mendemonstrasikan “arsitektur pulau” dalam bentuknya yang paling sederhana. Ini adalah gagasan bahwa pohon komponen interaktif kami tidak harus menggunakan seluruh situs web. Sebagai gantinya, kami dapat membuat pohon mini, atau "pulau", di seluruh aplikasi kami tergantung di mana kami benar-benar membutuhkan interaktivitas itu. Punya halaman arahan dasar tautan tanpa status apa pun untuk dikelola? Besar! Tidak perlu komponen interaktif. Tetapi apakah Anda memiliki formulir multi-langkah yang dapat memanfaatkan perpustakaan X React? Tidak masalah. Gunakan teknik seperti kode pendek react untuk memutar pulau Form.jsx .

Ini sejalan dengan gagasan "hidrasi parsial." Anda mungkin pernah mendengar istilah "hidrasi" jika Anda bekerja dengan SSG komponen-y seperti NextJS atau Gatsby. Singkatnya, ini adalah cara untuk:

  1. Render komponen Anda ke HTML statis terlebih dahulu.
    Ini memberi pengguna sesuatu untuk dilihat ketika mereka pertama kali mengunjungi situs web Anda.
  2. "Hidrasi" HTML ini dengan interaktivitas.
    Di sinilah kami menghubungkan kait dan penyaji status kami untuk, yah, membuat klik tombol benar-benar memicu sesuatu.

Pukulan 1-2 ini membuat kerangka kerja berbasis JS layak untuk situs statis. Selama pengguna memiliki sesuatu untuk dilihat sebelum JavaScript Anda selesai diurai, Anda akan mendapatkan skor yang layak pada metrik mercusuar tersebut.

Nah, sampai Anda tidak melakukannya. Mungkin mahal untuk "menghidrasi" seluruh situs web karena Anda memerlukan bundel JavaScript yang siap untuk memproses setiap elemen DOM terakhir . Tapi teknik shortcode kami tidak mencakup seluruh halaman! Sebagai gantinya, kami "sebagian" menghidrasi konten yang ada, memasukkan komponen hanya jika diperlukan.

Jangan Khawatir, Ada Plugin Untuk Semua Ini: Slinkity

Mari kita rekap apa yang kami temukan di sini:

  1. Vite adalah bundler yang sangat mampu yang dapat memproses sebagian besar jenis file ( jsx , vue , dan svelte untuk beberapa nama) tanpa konfigurasi tambahan.
  2. Kode pendek adalah cara mudah untuk menyisipkan potongan HTML ke dalam template kami, dengan gaya komponen.
  3. Kita dapat menggunakan kode pendek untuk merender bundel JS yang dinamis dan interaktif di mana pun kita inginkan menggunakan hidrasi parsial.

Jadi bagaimana dengan produksi yang dioptimalkan? Memuat gaya cakupan dengan benar? Heck, menggunakan .jsx untuk membuat seluruh halaman? Yah, saya telah menggabungkan semua ini (dan lebih banyak lagi!) ke dalam sebuah proyek bernama Slinkity. Saya senang melihat sambutan hangat dari komunitas terhadap proyek ini, dan saya ingin Anda, pembaca yang budiman, untuk mencobanya sendiri!

Coba panduan memulai cepat

Astro Cukup Hebat Juga

Pembaca dengan mata mereka pada teknologi mutakhir mungkin berpikir tentang Astro setidaknya sekali sekarang. Dan aku tidak bisa menyalahkanmu! Itu dibuat dengan tujuan yang hampir sama: mulai dengan HTML biasa, dan masukkan komponen stateful di mana pun Anda membutuhkannya. Heck, mereka bahkan akan membiarkan Anda mulai menulis komponen React di dalam komponen Vue atau Svelte di dalam file template HTML! Ini seperti edisi MDX Xtreme.

Ada satu biaya yang cukup besar untuk pendekatan mereka: Anda perlu menulis ulang aplikasi Anda dari awal. Ini berarti format template baru berdasarkan JSX (yang mungkin tidak nyaman bagi Anda), saluran data baru yang kehilangan beberapa hal bagus saat ini, dan masalah umum saat mereka menyelesaikan masalah.

Tapi memutar koktail 11ty + Vite dengan alat seperti Slinkity? Nah, jika Anda sudah memiliki situs 11ty, Vite harus masuk ke tempatnya tanpa penulisan ulang, dan kode pendek harus mencakup banyak kasus penggunaan yang sama seperti file .astro . Saya akui saat ini masih jauh dari sempurna. Tapi hei, sejauh ini berguna, dan saya pikir ini adalah alternatif yang cukup kuat jika Anda ingin menghindari penulisan ulang di seluruh situs!

Membungkus

Eksperimen Slinkity ini telah memenuhi kebutuhan saya sejauh ini (dan beberapa dari kalian juga!). Jangan ragu untuk menggunakan tumpukan apa pun yang berfungsi untuk JAM Anda. Saya hanya bersemangat untuk membagikan hasil tahun pembuatan alat pesta pora saya, dan saya sangat bersemangat untuk melihat bagaimana kita dapat menjembatani kesenjangan Jamstack yang hebat.

Bacaan lebih lanjut

Ingin menyelam lebih dalam ke hidrasi parsial, atau ESM, atau SSG secara umum? Lihat ini:

  • Arsitektur Kepulauan
    Posting blog dari Jason Format ini benar-benar memulai diskusi tentang "pulau" dan "hidrasi parsial" dalam pengembangan web. Ini penuh dengan diagram yang berguna dan filosofi di balik ide tersebut.
  • Sederhanakan statis Anda dengan generator situs statis yang dibuat khusus
    Artikel SmashingMag lain yang memandu Anda membuat pembuat situs web berbasis Node dari awal. Itu adalah inspirasi besar bagi saya!
  • Bagaimana Modul ES telah mendefinisikan ulang pengembangan web
    Postingan pribadi tentang bagaimana ES Modules telah mengubah game pengembangan web. Ini menyelam lebih jauh ke dalam sintaks impor "dulu dan sekarang" di web.
  • Pengantar komponen web
    Panduan yang sangat baik tentang apa itu komponen web, cara kerja shadow DOM, dan di mana komponen web terbukti berguna. Gunakan panduan ini untuk menerapkan komponen khusus ke kerangka kerja saya sendiri!