Ujung Depan: Menggunakan Gatsby.js dan Node.js untuk Pembaruan Situs Statis

Diterbitkan: 2022-03-11

Untuk beberapa persyaratan proyek, pembuatan halaman statis tidak hanya cukup , tetapi juga yang paling efisien dalam hal kecepatan dan skalabilitas.

Di paruh pertama seri ini, kami menggabungkan Node.js, Express, MongoDB, cron, dan Heroku untuk menghadirkan back end CI-ready yang menggunakan API GitHub sesuai dengan jadwal harian. Sekarang kami siap untuk menambahkan Gatsby ke dalam campuran untuk menyelesaikan proyek pembuatan halaman statis kami.

Mengembangkan Front End: Jadikan Situs Web Gatsby

Karena situs web Gatsby didasarkan pada React, akan sangat membantu jika Anda sudah terbiasa dengan cara membuat situs web dengan React.

Untuk penataan, saya lebih suka Bootstrap, reactstrap, dan react-markdown. Anda mungkin tahu bahwa catatan rilis di GitHub disimpan dalam format penurunan harga, oleh karena itu kami membutuhkan konverter.

Struktur Proyek Situs Web Statis

Struktur file/folder kami adalah sebagai berikut:

Root proyek front-end standar dengan folder publik kosong dan folder src untuk file seperti package.json. Di bawah folder src adalah subfolder gaya untuk global.css dan subfolder template untuk semua-repositori.js dan repositori.js.

Untuk apa file-file ini? Ayo lihat:

  • env.development dan env.production adalah file konfigurasi variabel lingkungan.
  • Template all-repositories.js akan digunakan untuk beranda kami, yang berisi daftar repositori.
  • Template repository.js akan digunakan untuk menampilkan detail untuk repositori yang diberikan.
  • gatsby-node.js adalah tempat kita menggunakan titik akhir back-end dan menjalankan metode createPage kita.
  • package.json , seperti biasa, berisi dependensi dan properti proyek.
  • global.css adalah file style sheet utama kami.

Implementasi Situs Web Gatsby

Seperti pada bagian belakang kami, jalankan npm install (atau yarn , jika Anda telah memasang Yarn) setelah menambahkan dependensi yang diperlukan ke package.json ujung depan:

 { // ... "dependencies": { "axios": "^0.18.0", "bootstrap": "^4.3.1", "gatsby": "^2.0.0", "react": "^16.5.1", "react-dom": "^16.5.1", "react-markdown": "^4.0.6", "reactstrap": "^7.1.0" } // ... }

File env.development dan env.production hanya memiliki URL back-end untuk lingkungan yang sesuai. Mantan memiliki:

 API_URL=http://localhost:3000

…sementara produksi memiliki:

 API_URL=https://[YOUR_UNIQUE_APP_NAME].herokuapp.com

gatsby-node.js hanya akan dijalankan sekali saat Anda membuat kode. Jadi kami harus mengumpulkan semua informasi yang diperlukan dari bagian belakang kami di sini. Kemudian, respons tersebut akan digunakan dengan templat kami untuk menghasilkan halaman statis yang sesuai.

Dalam kasus kami, all-repositories.js membutuhkan semua repositori, dan repository.js membutuhkan repositori yang sesuai untuk setiap iterasi. Terakhir, kita dapat menghasilkan jalur halaman secara dinamis, meneruskan owner repositori dan parameter name sebagai bagian dari bidang path :

 const axios = require('axios'); require("dotenv").config({ path: `.env.${process.env.NODE_ENV}` }); const getRepositoryData = async () => { console.log(process.env.API_URL); return axios.get(`${process.env.API_URL}/repositories`); }; exports.createPages = async ({ actions: { createPage } }) => { let repositories = await getRepositoryData(); repositories = repositories.data; // Create a page that lists all repositories. createPage({ path: `/`, component: require.resolve('./src/templates/all-repositories.js'), context: { repositories } }); // Create a page for each repository. repositories.forEach(repository => { createPage({ path: `/repository/${repository.owner}/${repository.name}`, component: require.resolve('./src/templates/repository.js'), context: { repository } }); }); };

Untuk all-repositories.js dan repository.js , jika kita menghilangkan gaya, kita hanya mengumpulkan data dari pageContext dan menggunakannya saat kita menggunakan parameter di React.

Di all-repositories.js , kita akan menggunakan bidang repositories dari pageContext seperti ini:

 export default ({pageContext: {repositories}}) => ( // ... <ListGroup> {/* Because the repositories parameter is a list, we are iterating over all items and using their fields */} {repositories.map(repository => (repository.tagName && <ListGroupItem className="repository-list-item"> // ... <Row> {`${repository.repositoryDescription}`} </Row> // ... </ListGroupItem> ))} </ListGroup> // ... );

Sedangkan untuk repository.js , kita akan menggunakan bidang repository dari pageContext :

 export default ({pageContext: {repository}}) => ( <div className="layout"> {repository.tagName && <ListGroupItem className="repository-list-item"> // ... <h1 className="release-notes">{`Release notes`}</h1> <hr/> {/* This the place where we will use Markdown-formatted release notes */} <ReactMarkdown source={`${repository.releaseDescription}`}/> </ListGroupItem> } // ... </div> );

Sekarang, pastikan bagian belakang Anda aktif dan berjalan. Anda akan ingat untuk proyek ini kami menetapkannya sebagai http://localhost:3000.

Selanjutnya, jalankan gatsby develop dari root proyek front-end Anda dan buka http://localhost:8000.

Jika Anda menambahkan beberapa repositori (pemilik/nama) ke bagian belakang Anda dan menjalankan fitur update-via-GitHub-API setidaknya sekali, Anda akan melihat sesuatu seperti ini:

Repositori yang mencantumkan halaman beranda aplikasi kami, menampilkan info dasar untuk contoh repo GitHub

Dan setelah mengklik salah satu repositori, Anda akan melihat sesuatu seperti ini:

Contoh halaman detail repositori, menampilkan informasi lebih lanjut tentang facebook/react GitHub repo

Setelah perubahan kami di atas, implementasi front-end kami selesai.

Besar! Sekarang kita hanya perlu menyebarkan.

Menyebarkan Front End

Kami tidak perlu melakukan perubahan apa pun pada aplikasi front-end kami di bagian ini. Kami hanya akan menyebarkannya ke Netlify—Anda memerlukan akun di sana.

Tapi pertama-tama, kita harus menerapkan kode kita ke GitHub, GitLab, atau Bitbucket. Seperti halnya back end, saya menerapkan kode saya ke GitHub.

Kemudian, masuk ke Netlify dan klik tombol "Situs baru dari Git" di dasbor Anda. Ikuti langkah-langkah di layar untuk memilih penyedia Git Anda dan menemukan repositori Anda.

Untuk langkah terakhir, jika Anda menyusun kode Anda dengan benar, Netlify akan secara otomatis mengatur perintah build dan publish direktori dengan benar sebagai berikut:

Pengaturan yang benar untuk opsi build Netlify: Deploy master, gunakan "gatsby build" sebagai perintah build, dan publikasikan ke direktori "public/".

Kemudian klik "Sebarkan situs." Ini akan menyebarkan situs Anda ke subdomain Netlify yang dibuat secara acak, tetapi Anda dapat mengubahnya kapan saja—saya mengubah penerapan saya ke https://sample-create-page-api-gatsby.netlify.com, tempat Anda dapat menemukan demo langsung dari aplikasi yang telah selesai.

Sejauh ini bagus. Tetapi karena ini adalah aplikasi halaman statis, kami harus membangunnya kembali setiap hari agar tetap mutakhir.

Pembaruan Harian Menggunakan Build Hook

Kait build di Netlify berfungsi sebagai pemicu build, sehingga Anda dapat memicunya dari bagian belakang setelah tugas cron selesai. Untuk melakukan itu, pertama-tama buat build hook di Netlify.

Di bawah bagian “Build & deploy → Continuous Deployment”, Anda dapat menemukan “Build hooks.” Klik "Tambahkan kait bangunan."

Di mana menemukan kait pembuatan di Netlify

Beri nama dan simpan. (Saya memanggil build-from-backend milik saya.) Kemudian salin tautan yang dihasilkannya.

Sekarang mari kita buka proyek back-end kita dan tambahkan beberapa baris ini ke file cron.controller.js . Kami hanya mengirimkan permintaan POST ke URL build-hook Netlify.

 const Axios = require('axios'); const Config = require('../config/env.config'); const NETLIFY_BUILD_HOOK_URI = Config.netlifyEndpoint; function updateGatsby() { if (NETLIFY_BUILD_HOOK_URI) { console.log('Gatsby build request will be send'); Axios.post(NETLIFY_BUILD_HOOK_URI).then(() => { console.log('Gatsby build request was successful'); }); } }

Kemudian perbarui fungsi updateDaily kami:

 function updateDaily() { RepositoryController.updateRepositories().then(() => { updateGatsby(); }); }

Terakhir, perbarui file env.config.js kami untuk mengatur properti netlifyEndpoint yang akan dikumpulkan dari variabel lingkungan:

 "netlifyEndpoint": process.env.NETLIFY_BUILD_HOOK || ""

Sekarang, Anda harus mengatur variabel lingkungan NETLIFY_BUILD_HOOK yang Anda salin dari Netlify beberapa saat yang lalu. Di Heroku, Anda dapat mengatur variabel lingkungan dari bagian "pengaturan" aplikasi Anda.

Setelah mendorong komit Anda, aplikasi back-end akan mengirimkan permintaan build ke Netlify dan halaman Anda akan diperbarui setiap hari, di akhir tugas cron Anda. Berikut tampilan repo setelah menambahkan fungsionalitas build hook, bersama dengan versi final repo back-end dan repo front-end.

Sebagai sentuhan akhir pada proyek, kami akan menunjukkan cara menggunakan fungsi AWS Lambda yang dipicu oleh AWS CloudWatch yang akan membangunkan back end Anda tepat waktu untuk setiap pembaruan harian.

Permintaan Sederhana AWS Lambda dan AWS CloudWatch

AWS Lambda adalah platform komputasi tanpa server. Kami hanya membutuhkan dasar-dasar platform ini untuk tujuan kami di sini. Anda memerlukan akun AWS.

Pertama, masuk ke AWS dengan akun Anda dan temukan Lambda Management Console. Misalnya, untuk us-east-2 , dapat ditemukan di https://us-east-2.console.aws.amazon.com/lambda/home.

Jika belum dipilih, buka bagian "Fungsi":

Bagian "Fungsi" AWS Lambda

Di sini, kami akan membuat fungsi kami dari awal dengan mengklik "Buat fungsi." Mari kita beri nama yang jelas. Kami akan menggunakan Node.js sebagai bahasa runtime. Kemudian klik "Buat fungsi" berikutnya untuk menyelesaikannya.

Halaman "Buat fungsi" AWS Lambda, diisi di create triggerMyBackendAtUTCMidnight dengan runtime Node.js dan peran baru dengan izin Lambda dasar

Ini akan mengarahkan kita ke halaman fungsi baru di mana kita dapat menulis kode kita di index.js .

Mari kita implementasikan fungsi lambda pertama kita. Karena kami tidak memiliki dependensi pihak ketiga, kami harus menggunakan modul inti Node.js. (Jika Anda ingin mengaktifkan dependensi pihak ketiga, ikuti panduan ini dari AWS.)

Pastikan nama metode yang diekspor ( handler dalam kasus ini) cocok dengan parameter “Handler” di halaman:

Parameter Handler dengan "index.handler" sebagai nilainya

Selebihnya adalah permintaan GET sederhana ke bagian belakang Anda:

 const https = require('https'); exports.handler = async (event) => { return new Promise((resolve, reject) => { https.get(process.env.HEROKU_APP_URL, (resp) => { let data = ''; resp.on('data', (chunk) => { data += chunk; }); resp.on('end', () => { resolve(JSON.parse(data)); }); }).on("error", (err) => { reject("Error: " + err.message); }); }); };

Pastikan Anda menyetel variabel lingkungan HEROKU_APP_URL di halaman, dan simpan konfigurasi Anda:

Menyetel variabel lingkungan yang diperlukan di AWS Lambda. Nilai yang ditampilkan adalah https://sample-github-api-consumer-nod.herokuapp.com/repositories.

Satu langkah terakhir adalah menambahkan aturan pemicu CloudWatch untuk menjalankan fungsi ini sepuluh menit sebelum setiap pembaruan harian—dalam seri artikel ini, yang bekerja hingga 23:50:

Mengonfigurasi Acara CloudWatch untuk menambahkan aturan pemicu

Jenis aturan pemicu CloudWatch kami akan menjadi "Ekspresi jadwal" dan, menurut format yang diterima, ekspresi cron kami akan menjadi cron(50 23 * * ? *) .

Halaman "Konfigurasi pemicu" AWS CloudWatch, disetel untuk membuat aturan baru yang disebut cronDailyUpdate dengan ekspresi yang diberikan di atas dan pemicu diaktifkan

Kami sekarang telah mengonfigurasi fungsi AWS Lambda kami untuk dipicu oleh aturan CloudWatch kami.

Sekarang Mendukung Halaman Web Statis Kami: Gatsby/React dan Netlify

Dengan sedikit AWS Lambda/CloudWatch ditambahkan ke back end Node.js/MongoDB/Heroku kami, dan Gatsby dan Netlify menghasilkan dan menghosting front end kami, aplikasi kami selesai!

Saya membagikan tautan demo langsung sebelumnya, tetapi jangan ragu untuk juga memeriksa versi prototipe saya yang disempurnakan—ada beberapa perubahan tambahan yang saya tahu Anda akan menyukainya.

Anda dapat menggunakan ini sebagai cetak biru untuk proyek serupa—saya harap artikel ini akan membantu Anda membuat prototipe aplikasi dengan cara yang lebih cepat dan hemat biaya. Terima kasih sudah membaca!

Toptal adalah Mitra Konsultasi AWS Tingkat Lanjut.