de Emmanuel Yusufu
Table of Contents
Cum să construiești un blog React și Gatsby în aproximativ 10 minute

Declinare de responsabilitate: Aceasta a fost scrisă pentru versiunea 1 Gatsby, versiunea 2 tocmai a fost lansată și a făcut unele modificări. Voi lucra la un alt tutorial pentru asta.
Gatsby este un generator de site static rapid și rapid, bazat pe ReactJS.
A generator de site static (SSG) este un compromis între un cod HTML codat site static și un CMS complet (Content Management System), precum Wordpress.
Un SSG poate fi utilizat pentru a genera pagini HTML pentru site-uri web bazate pe conținut (cum ar fi blogurile). Tot ce necesită sunt date pentru conținutul paginii și șablonul care trebuie completat cu conținut.
Această postare va fi împărțită în cinci secțiuni:
- Noțiuni de bază.
- Crearea componentelor de aspect.
- Crearea postărilor de blog.
- Generarea de pagini noi din datele postărilor pe blog.
- Creați o listă a fișierelor de reducere a site-ului nostru în pagina de destinație.
Vom face o scufundare profundă în Gatsby și unele dintre caracteristicile sale, creând un blog static imaginar numit CodeStack. Mașina este prezentată mai jos. Sa mergem! ✌️

1. Noțiuni de bază
Condiții prealabile
Mai întâi, asigurați-vă că aveți instalat Node.js pe sistemul dvs. Dacă nu, mergeți la nodejs.org și instalați o versiune recentă pentru sistemul dvs. de operare.
De asemenea, acest articol presupune că înțelegeți ReactJS.
Instalați CLI
Gatsby are un instrument de linie de comandă care oferă comenzi utile precum:
-
gatsby new
: pentru schela unui nou proiect Gatsby. -
gatsby develop
: pentru lansarea unui server de dezvoltare web activat pentru reîncărcare la cald. -
gatsby build
: pentru construirea unei versiuni gata de producție a proiectului.
Pentru a instala, tastați următoarele pe terminal și apăsați Enter:
npm install --global gatsby-cli
Permite crearea unui folder de proiect codestack-blog
și navigați către terminal.
gatsby new codestack-blog && cd $_
Dacă executați gatsby develop
în dosarul proiectului, site-ul cu schele ar trebui să arate astfel:

Adăugarea de pluginuri
Gatsby are o mare și set în creștere de pluginuri. Acestea sunt în esență pachete Node.js care interacționează cu API-urile lui Gatsby.
Acestea pot fi instalate prin NPM (Node Package Manager) pe terminal și, în general, au trei categorii: funcţional, sursă și transformator pluginuri.
Plugin-uri funcționale
Aceste pluginuri oferă funcționalități suplimentare pe un site Gatsby sau în mediul său de dezvoltare. Pentru aplicația noastră, vom avea nevoie de:
-
gatsby-plugin-react-helmet
: permite modificarea fișieruluihead
Etichete. Observați că este deja instalat în proiectul nostru cu schele. -
gatsby-plugin-catch-links
: Interceptă linkurile locale de la markdown și alte pagini care nu reacționează și face un pushState din partea clientului pentru a evita ca browserul să trebuiască să actualizeze pagina.
Instalați pluginurile sau doar al doilea plugin.
npm install gatsby-plugin-react-helmet gatsby-plugin-catch-links
De fiecare dată când adăugăm un nou plugin, trebuie să actualizăm fișierul gatsby-config.js
fișier cu noul plugin, astfel încât Gatsby să îl recunoască și să îl folosească. Folosim căpușe.
module.exports = { siteMetadata: { title: `Gatsby Default Starter`, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-catch-links`, ],}
Plugin-uri sursă
Aceste plugin-uri „sursă” date din locații la distanță sau locale în ceea ce Gatsby numește noduri. Pentru a scrie postările noastre în Markdown pe discul nostru local, avem nevoie de:
-
gatsby-source-filesystem
: obține date despre fișiere din sistemul de fișiere al computerului.
npm install gatsby-source-filesystem
Actualizați fișierul gatsby-config.js
fişier:
module.exports = { siteMetadata: { title: `Gatsby Default Starter`, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-catch-links`, { resolve: `gatsby-source-filesystem`, options: { path: `${__dirname}/src/pages`, name: 'pages', }, } ],}
Ce se petrece aici? Un options
obiectul poate fi transmis unui plugin pentru mai multe configurări. Trecem sistemul de fișiere path
(adică unde vor fi localizate fișierele noastre Markdown), apoi a name
pentru fișierele sursă, astfel încât Gatsby să știe despre fișierele noastre sursă și unde să aplice pluginurile transformatorului.
Pluginuri pentru transformatoare
Aceste pluginuri transformă datele brute din noduri în formate de date utilizabile. De exemplu, vom avea nevoie de:
-
gatsby-transformer-remark
: transformă postările de blog scrise în markdown.md
fișierele de pe discul local în HTML pentru redare.
npm install gatsby-transformer-remark
Actualizați fișierul gatsby-config.js
fișier din nou.
module.exports = { siteMetadata: { title: `Gatsby Default Starter`, }, plugins: [ `gatsby-plugin-react-helmet`, `gatsby-plugin-catch-links`, { resolve: `gatsby-source-filesystem`, options: { path: `${__dirname}/src/pages`, name: 'pages', }, }, `gatsby-transformer-remark`, ],}

2. Crearea componentelor Layout
Gatsby vă permite să creați cu ușurință „componente de aspect”. Componentele de aspect sunt secțiuni ale site-ului dvs. pe care doriți să le partajați pe mai multe pagini. Pentru blogul pe care îl construim, acestea sunt antetul și barele laterale.
Din folderul rădăcină, aruncați o privire la src/layouts
. Veți descoperi un index.js
fișier în care definim componentele de aspect. index.css
a venit deja cu stiluri.
După explorarea index.js
fișier, veți vedea că au fost deja create două componente: Header
și TemplateWrapper
. În TemplateWrapper
, înfășurăm conținutul site-ului nostru cu componente de aspect care dorim să fie prezente pe mai multe pagini.
Acest lucru este posibil de către children()
recuzită. Acesta va reda toate componentele non-layout ale site-ului nostru unde este plasat. Observați că, spre deosebire de recuzita pentru copii React, recuzita pentru copii transmisă componentelor de aspect este o funcție și trebuie executată.
În primul rând, creați un folder nou și un fișier CSS la src/styles/layout-overide.css
. Adăugați la lista importurilor din index.js
fişier. Avem nevoie să Importați-l după index.css
pentru a suprascrie unele reguli de stil existente.
import React from 'react'import PropTypes from 'prop-types'import Link from 'gatsby-link'import Helmet from 'react-helmet'
import './index.css'import "../styles/layout-overide.css";
Deschis layout-overide.css
și lipiți următoarele reguli de stil. Nu este nevoie să-i dai seama.
* { background: #f5f5f5; color: black;}html { height: 100%;}
body { height: 100%; border: 5px solid #ffdb3a;}
h1 { font-size: 1.5rem; line-height: 0.5rem;}
p, div { font-size: 16px;}
Actualizați componenta antet.
const Header = () => ( <div style={{ background: '#f5f5f5', marginBottom: '3rem', borderBottom: '2px solid #e6e6e6', }} > <div style={{ margin: '0 auto', maxWidth: 980, padding: '1.45rem 1.0875rem', }} > <h1 style={{margin: 0, textAlign: 'center',fontSize: '18px'}}> <Link to="/" style={{ color: 'black', textDecoration: 'none', }} > CodeStack </Link> </h1> </div> </div>);
De asemenea, creați un fișier Sidebar
componentă.
const Sidebar = (props) => (
<div style={{ border: '2px solid #e6e6e6', maxWidth: 960, padding: '0.5rem', marginBottom: '25px' }} > <strong>{props.title}.</strong> {props.description}</div>
);
Ne dorim Sidebar
și redat {children()}
componente care să se comporte într-un mod receptiv astfel:

Deoarece nu există o modalitate ușoară de a defini interogări media în React, am găsit o bibliotecă numită react-media
, o componentă de interogare media CSS pentru React. Instalați-l.
npm install --save react-media
Oferă un <Med
ia> componentă care ascultă potrivirile unei interogări media CSS și redă lucruri în funcție de potrivirea interogării sau nu.
Adăugați-l la lista de importuri din fișierul nostru.
import Media from 'react-media'
Permite aspectul totul în ( Header
, Sidebar
, și children()
componente) modul în care ne dorim TemplateWrapper
. Efectuați următoarele modificări (scuzați ștecherul nerușinat al numelui meu):
const TemplateWrapper = ({ children }) => ( <div> <Helmet title="Gatsby Default Starter" meta={[ { name: "description", content: "Sample" }, { name: "keywords", content: "sample, something" } ]} /> <Header /> <div style={{ margin: "0 auto", maxWidth: 980, display: "flex", flexDirection: "row", justifyContent: "space-between", height: "100%" }} > <Media query={{ maxWidth: 848 }}> {matches => matches ? ( <div style={{ margin: "0 auto", maxWidth: 980, display: "flex", flexDirection: "row", justifyContent: "space-between", height: "100%", padding: "25px" }} > <div style={{ flex: 1 }}>{children()}</div> </div> ) : ( <div style={{ margin: "0 auto", maxWidth: 980, display: "flex", flexDirection: "row", justifyContent: "space-between", height: "100%", padding: "25px" }} > <div style={{ flex: 2.5, paddingRight: "30px" }}> {children()} </div>
<div style={{ flex: 1 }}> <Sidebar title="Codestack" description="Articles on React and Node.js. All articles are written by Me. Fullstack Web Development." /> <Sidebar title="About author" description="I am a Full-stack Web Developer specializing in React and Node.js based in Nigeria." /> </div> </div> ) } </Media> </div> </div>);

Ce se întâmplă în acel bloc monolitic de cod? React media folosește un Operație ternară pentru a determina ce să redăm pe baza unui lățimea maximă de 848 px . Când ecranul se potrivește cu lățimea, numai Header
și children()
componentele sunt redate.
<Media query={{ maxWidth: 848 }}> {matches => matches ? ( ...stuff to render... ) : ( ...stuff to render... ) } </Media>

condition
este true
, operatorul returnează valoarea lui expr1
; în caz contrar, returnează valoarea lui expr2
.Dacă ați observat, am folosit și Flexbox pentru a dispune pozițiile fișierului children()
și Sidebar
componente.
Alerga gatsby develop
pe terminal și blogul nostru static ar trebui să arate astfel:

3. Crearea postărilor de pe blog
Acum permiteți-ne să creăm postări reale de blog. Gatsby folosește GraphQL pentru a prelua date dintr-una sau mai multe surse, cum ar fi discul dvs. local, Wordpress API și așa mai departe.
Personal, îmi place faptul că pot crea un blog static și să extrag conținut dintr-un API WordPress. Clientul meu are acces la Editorul Wordpress unde creează postări și evit să mă ocup de toate problemele legate de dezvoltarea unui site Wordpress.
În această postare, vom încărca datele din fișierele Markdown pe care le vom crea pe discul nostru local. gatsby-source-filesystem
pluginul pe care l-am configurat mai devreme se așteaptă ca conținutul nostru să fie inclus src/pages
, deci exact acolo o vom pune!
O practică obișnuită pentru postările de pe blog este de a denumi folderul ca titlul MM-ZZ-AAAA. Puteți să-l numiți orice doriți sau doar să plasați un fișier de marcare în interiorul /pages
pliant.
Să creăm un folder src/pages/12–22–2017-first-post
, și plasează un index.md
interior. Scrie:
---path: "/hello-world"date: "2017-07-12T17:12:33.962Z"title: "My First Gatsby Post"---
Oooooh-weeee, my first blog post!
First post Ipsum is a major key to success. Congratulations, you played yourself. Surround yourself with angels. Celebrate success right, the only way, apple. The key is to drink coconut, fresh coconut, trust me. Egg whites, turkey sausage, wheat toast, water. Of course they don’t want us to eat our breakfast, so we are going to enjoy our breakfast.
Blocul înconjurat în liniuțe este denumit frontmatter
. Datele pe care le specificăm aici, precum și alte fișiere Markdown, vor fi recunoscute de gatsby-transformer-remark
conecteaza.
Pluginul va converti partea de metadate frontmatter a fișierului dvs. de reducere în frontmatter
și partea de conținut (Yippeeee, prima mea postare pe blog!) în HTML.
Când începem să generăm pagini de blog direct din fișiere de markdown în secțiunea 4 (secțiunea următoare), path
va fi folosit pentru a specifica calea URL pentru redarea fișierului. De exemplu, fișierul de reducere de mai sus va fi redat la localhost:8000/hello-world
.
Înainte de aceasta, permiteți crearea unui șablon care va reda orice fișier de reducere în propria sa pagină de blog. Creați fișierul src/templates/blog-post.js
(vă rugăm să creați fișierulsrc/templates
pliant).
import React from "react";import Helmet from "react-helmet";
export default function Template({ data }) { const post = data.markdownRemark; return ( <div className="blog-post-container"> <Helmet title={`CodeStack - ${post.frontmatter.title}`} /> <div className="blog-post"> <h1>{post.frontmatter.title}</h1> <div className="blog-post-content" dangerouslySetInnerHTML={{ __html: post.html }} /> </div> </div> );}
Am înființat Template
componentă pentru a primi un data
obiect care va proveni din interogarea GraphQL pe care urmează să o scriem.
Încă o dată, interogarea GraphQL este necesară pentru a prelua date în componentă. Rezultatul interogării este injectat de Gatsby în componenta Șablon ca data
și markdownRemark
.
Vom constata că markdownRemark
proprietatea conține toate detaliile fișierului Markdown.
Să facem de fapt interogarea. Ar trebui să fie plasat sub Template
componentă:
export const pageQuery = graphql` query BlogPostByPath($path: String!) { markdownRemark(frontmatter: { path: { eq: $path } }) { html frontmatter { date(formatString: "MMMM DD, YYYY") path title } } }`;
Dacă nu sunteți familiarizați cu GraphQL, voi încerca să descompun ce se întâmplă aici. Pentru a afla mai multe despre GraphQL, luați în considerare acest lucru resursă excelentă.
GraphQL este doar ideea Facebook a unui anumit tip de server. Au scris o specificație cu privire la tipul de solicitări care pot fi trimise către acel server și modul în care acesta ar trebui să răspundă. API-ul GraphQL este mai bun decât REST, deoarece descrieți datele exacte de care are nevoie partea clientului, astfel încât să nu mai existe preluarea sau preluarea excesivă a datelor.
Aceasta înseamnă că trebuie să vă creați propriul server GraphQL. Din fericire pentru noi, GatsbyJS vine cu propriul server GraphQL.
În codul de mai sus, BlogPostByPath
este interogarea de bază care va duce la returnarea unei postări pe blog. Va fi returnat ca data
pentru injectare în Template
componentă.
Trecem BlogPostByPath
$path
argument pentru a returna o postare de blog legată de calea pe care o vizualizăm în prezent.
Mai mult, amintește-ți markdownRemark
a transformat fișierele noastre de reducere. Acesta va fi tratat ca o proprietate al cărei conținut va fi disponibil prin data.markdownRemark
.
Am putea accesa codul HTML prin data.markdownRemark.html
. De asemenea frontmatter
conținutul pe care l-am creat cu un bloc de dahes poate fi accesat prin data.markdownRemark.title
etc.
Intregul blog-template.js
ar trebui să arate așa:
import React from "react";import Helmet from "react-helmet";
export default function Template({ data }) { const post = data.markdownRemark; return ( <div className="blog-post-container"> <Helmet title={`CodeStack - ${post.frontmatter.title}`} /> <div className="blog-post"> <h1>{post.frontmatter.title}</h1> <div className="blog-post-content" dangerouslySetInnerHTML={{ __html: post.html }} /> </div> </div> );}
export const pageQuery = graphql` query BlogPostByPath($path: String!) { markdownRemark(frontmatter: { path: { eq: $path } }) { html frontmatter { date(formatString: "MMMM DD, YYYY") path title } } }`;
In acest punct:
- Avem o grămadă de pluginuri instalate pentru a efectua unele utilități, precum și pentru a încărca fișiere de pe disc și a transforma Markdown în HTML.
- Avem un singur fișier Markdown singuratic care va fi redat ca o postare pe blog.
- Avem un șablon React pentru redarea postărilor de blog într-un aspect, precum și un GraphQL conectat pentru a interoga datele postărilor de blog și injecta șablonul React cu datele interogate.
Dulce!
4. Generarea de pagini noi din datele postărilor pe blog.
Gatsby oferă un API Node, care oferă funcționalități pentru crearea de pagini dinamice din postări de blog. Acest API este expus îngatsby-node.js
în directorul rădăcină al proiectului dvs. Acest fișier ar putea exporta mai multe API-uri de nod, dar suntem interesați de createPages
API.
Utilizați următorul bloc de fragment de cod ca furnizate în documentele oficiale (Rețineți că calea blogPostTemplate a fost setată pentru a o reflecta pe a noastră):
const path = require('path');
exports.createPages = ({ boundActionCreators, graphql }) => { const { createPage } = boundActionCreators;
const blogPostTemplate = path.resolve(`src/templates/blog-post.js`);
return graphql(`{ allMarkdownRemark( sort: { order: DESC, fields: [frontmatter___date] } limit: 1000 ) { edges { node { excerpt(pruneLength: 250) html id frontmatter { date path title } } } } }`) .then(result => { if (result.errors) { return Promise.reject(result.errors); }
result.data.allMarkdownRemark.edges .forEach(({ node }) => { createPage({ path: node.frontmatter.path, component: blogPostTemplate, context: {} // additional data can be passed via context }); }); });}
Verificați dacă funcționează. Vă recomandăm să vă închideți fereastra de broswer, oprind-o gatsby develop
server de la terminal folosind ctrl c
. Acum fugi gatsby develop again
și deschis http://localhost:8000/hello-world
.

Creați un alt fișier src/pages/24–12–2017-learning-grid/index.md
---path: "/another-one"date: "2017-07-12T17:12:33.962Z"title: "My Second Gatsby Post"---
In life there will be road blocks but we will over come it. Special cloth alert. Don’t ever play yourself. The key to more success is to get a massage once a week, very important, major key, cloth talk.
<pre><code>// some css grid code </code></pre>
Încă o dată, închideți fereastra broswer, opriți-vă gatsby develop
Server. Alerga gatsby develop again
și deschis http://localhost:8000/another-one
. Aceasta este arătată:

Continuați dacă doriți și creați-vă propriile pagini. ✌
5. Creați o listă a fișierelor de reducere a site-ului nostru în pagina de destinație.
Pagina de destinație implicită care vine împreună cu site-ul Gatsby eșafodat se află la src/pages/index.js
. Aici am defini un șablon și am face o interogare pentru a-l injecta cu date pentru lista de .md
fișiere. Fa asta:
import React from "react";import Link from "gatsby-link";import Helmet from "react-helmet";
import '../styles/blog-listing.css';
export default function Index({ data }) { const { edges: posts } = data.allMarkdownRemark; return ( <div className="blog-posts"> {posts .filter(post => post.node.frontmatter.title.length > 0) .map(({ node: post }) => { return ( <div className="blog-post-preview" key={post.id}> <h1> <Link to={post.frontmatter.path}>{post.frontmatter.title}</Link> </h1> <h2>{post.frontmatter.date}</h2> <p>{post.excerpt}</p> </div> ); })} </div> );}
export const pageQuery = graphql` query IndexQuery { allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) { edges { node { excerpt(pruneLength: 250) id frontmatter { title date(formatString: "MMMM DD, YYYY") path } } } } }`;

Sper că sunteți ticăloși în acest moment și deja familiarizați cu ce se întâmplă. Rețineți că am scris un import
mai sus că nu există. Acum creați fișierul /styles/blog-listing.css
:
div.blog-post-preview { border-bottom: 2px solid #e6e6e6; padding-top: 1rem; padding-bottom: 1rem; margin-bottom: 1rem;}
h1 > * { font-size: 1.2rem; text-decoration-line: none;}
h2 { font-size: 0.8rem !important; font-weight: 100 !important;}
Reporniți serverul, accesați pagina de destinație și ar trebui să vedeți lista la locul de muncă:

Concluzie
Am ajuns la sfârșitul acestui tutorial. Vă mulțumesc că ați citit până acum.
Această postare este doar vârful aisbergului, având în vedere cantitatea de lucruri pe care le-ai putea face cu Gatsby. Simțiți-vă liber să explorați cum ați putea implementa:
- Funcționalitate de căutare
- Utilizarea etichetelor pentru a clasifica postările de pe blog
- Implementarea site-ul dvs. Gatsby
Puteți obține codul sursă final aici. Simțiți-vă liber să mă sprijiniți (devapparel.co) și arată bine în timp ce te uiți la el. De asemenea, comentează sau distribuie această postare. Mulțumesc pentru lectură!
PS Lucrez la o carte React cu Ohans Emmanuel asta te-ar face să stăpânești React construind 30 de proiecte mici în 30 de zile. Dacă doriți să fiți la curent cu acest lucru, înscrieți-vă lista de corespondență. Mulțumiri!