Ujung Depan: Menggunakan Gatsby.js dan Node.js untuk Pembaruan Situs Statis
Diterbitkan: 2022-03-11Untuk 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:
Untuk apa file-file ini? Ayo lihat:
-
env.development
danenv.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 metodecreatePage
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:
Dan setelah mengklik salah satu repositori, Anda akan melihat sesuatu seperti ini:
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:

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."
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":
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.
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:
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:
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:
Jenis aturan pemicu CloudWatch kami akan menjadi "Ekspresi jadwal" dan, menurut format yang diterima, ekspresi cron kami akan menjadi cron(50 23 * * ? *)
.
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!