Gatsby.js en détail


Comme vous le savez, vous ne pouvez pas aller loin sur certains passe-plats seuls, vous devez donc approfondir toutes les technologies pour apprendre à écrire quelque chose de valable. Cet article traite des détails de Gatsby.js , dont la connaissance vous permettra de créer et de maintenir des sites Web et des blogs complexes.


Article précédent sur la création et la publication d'un blog personnel à l'aide de JAM-stack

Sujets abordés ci-dessous:



La préparation


Installer Gatsby sur PC
yarn global add gatsby-cli 

Clonage d'un projet minimal
  npx gatsby new gatsby-tutorial https://github.com/gatsbyjs/gatsby-starter-hello-world cd gatsby-tutorial 

Initialisation du référentiel
  git init git add . git commit -m "init commit" 

Bilan de santé
  yarn start 

S'il n'y a pas d'erreurs dans la console et dans le navigateur le long du chemin http: // localhost: 8000, vous voyez "Bonjour tout le monde!" cela signifie que tout fonctionne correctement. Vous pouvez essayer de modifier le contenu du fichier /src/pages/index.js pour vérifier le rechargement à chaud.


Structure et routage des pages


Pour créer une page dans Gatsby, placez simplement le nouveau fichier dans le dossier / src / pages et il sera compilé dans une page HTML séparée. Il est important de noter que le chemin d'accès à cette page correspondra au chemin réel avec le nom . Par exemple, ajoutez quelques pages supplémentaires:


 src └── pages ├── about.js ├── index.js └── tutorial ├── part-four.js ├── part-one.js ├── part-three.js ├── part-two.js └── part-zero.js 

Le contenu n'est pas encore important, donc n'importe quel texte peut être utilisé pour distinguer les pages.


 import React from "react"; export default () => <div>Welcome to tutorial/part-one</div>; 

Vérifiez dans le navigateur:



De cette façon, lors de la structuration des fichiers, vous pouvez immédiatement résoudre les problèmes de routage.


Il existe également une API createPage spéciale avec laquelle vous pouvez contrôler de manière plus flexible les chemins et les noms des pages, mais pour y travailler, nous avons besoin de comprendre comment les données fonctionnent dans Gatsby, nous allons donc l'examiner un peu plus loin dans l'article.

Combinez les pages créées à l'aide des liens, pour cela, nous utilisons le composant <Link /> du package Gatsby, qui a été créé spécifiquement pour la navigation interne. Pour tous les liens externes, utilisez la balise <a> régulière.


/src/pages/index.js


 import React from "react"; import { Link } from "gatsby"; export default () => ( <div> <ul> <li> <Link to="/about">about</Link> </li> <li> <Link to="/tutorial/part-zero">Part #0</Link> </li> <li> <Link to="/tutorial/part-one">Part #1</Link> </li> <li> <Link to="/tutorial/part-two">Part #2</Link> </li> <li> <Link to="/tutorial/part-three">Part #3</Link> </li> <li> <Link to="/tutorial/part-four">Part #4</Link> </li> </ul> </div> ); 

<Link> sous le capot a un mécanisme très délicat pour optimiser le chargement des pages et est donc utilisé à la place de <a> pour naviguer sur le site. Plus de détails peuvent être trouvés ici .

navigation


Des pages sont créées, des liens sont ajoutés, il s'avère que la navigation est terminée.


Composants, modèles et leur interaction


Comme vous le savez, dans tout projet, il y a toujours des éléments répétitifs, pour les sites Web, c'est un en-tête, un pied de page, une barre de navigation. De plus, les pages, quel que soit leur contenu, sont construites selon une certaine structure, et comme Gatsby est un compilateur pour React , la même approche de composant est utilisée pour résoudre ces problèmes.


Créez les composants pour l'en-tête et le panneau de navigation:


/src/components/header.js


 import React from "react"; import { Link } from "gatsby"; /** *         *  ,     React-. *      ,    *  " ".     *    ""  GraphQL  gatsby- */ import logoSrc from "../images/logo.png"; export default () => ( <header> <Link to="/"> <img src={logoSrc} alt="logo" width="60px" height="60px" /> </Link> That is header </header> ); 

/src/components/sidebar.js


 import React from "react"; import { Link } from "gatsby"; export default () => ( <div> <ul> <li> <Link to="/about">about</Link> </li> <li> <Link to="/tutorial/part-zero">Part #0</Link> </li> <li> <Link to="/tutorial/part-one">Part #1</Link> </li> <li> <Link to="/tutorial/part-two">Part #2</Link> </li> <li> <Link to="/tutorial/part-three">Part #3</Link> </li> <li> <Link to="/tutorial/part-four">Part #4</Link> </li> </ul> </div> ); 

et ajoutez-les à /src/pages/index.js


 import React from "react"; import Header from "../components/header"; import Sidebar from "../components/sidebar"; export default () => ( <div> <Header /> <Sidebar /> <h1>Index page</h1> </div> ); 

Nous vérifions:


index_page


Tout fonctionne, mais nous devons importer l'en-tête et la barre latérale sur chaque page séparément, ce qui n'est pas très pratique, et pour résoudre ce problème, il suffit de créer un composant de mise en page et d'envelopper chaque page avec.


Disposition Gatsby == réagir conteneur
oui, ce n'est pas une égalité stricte, parce que c'est "presque" la même chose

/src/components/layout.js


 import React from "react"; import Header from "./header"; import Sidebar from "./sidebar"; export default ({ children }) => ( <> <Header /> <div style={{ margin: `0 auto`, maxWidth: 650, backgroundColor: `#eeeeee` }} > <Sidebar /> {children} </div> </> ); 

/src/pages/index.js (et toutes les autres pages)


 import React from "react"; import Layout from "../components/layout"; export default () => ( <Layout> <h1>Index page</h1> </Layout> ); 

Terminé, regardez le navigateur:


mise en page


Pourquoi le projet contient-il tous les noms de fichiers avec une lettre minuscule? Pour commencer, déterminons que l’espace de noms pour React vient du fait que "chaque fichier est une classe, et la classe est toujours en majuscule". Dans Gatsby, les fichiers contiennent toujours des classes, mais il y a un «mais» - «chaque fichier est une page potentielle, et son nom est l'URL de cette page». La communauté est arrivée à la conclusion que les liens comme http://domain.com/User/Settings ne sont pas comme-il-faut et ont approuvé le cas de kebab pour les noms de fichiers.

Structure des fichiers
  src ├── components │ ├── header.js │ ├── layout.js │ └── sidebar.js ├── images │ └── logo.png └── pages ├── about.js ├── index.js └── tutorial ├── part-eight.js ├── part-five.js ├── part-four.js ├── part-one.js ├── part-seven.js ├── part-six.js ├── part-three.js ├── part-two.js └── part-zero.js 

Travailler avec des données


Maintenant que la structure du site est prête, vous pouvez procéder au remplissage du contenu. L'approche classique du "hardcode" ne convenait pas aux créateurs de la pile JAM, ainsi qu'au "rendu du contenu à partir des requêtes AJAX" et ils ont donc suggéré de remplir les sites avec du contenu au moment de la compilation. Dans le cas de Gatsby , GraphQL est responsable de cela, ce qui vous permet de travailler facilement avec des flux de données provenant de toutes les sources.


Il est impossible de parler de GraphQL en bref, il est donc conseillé de l'étudier vous-même ou d'attendre mon prochain article. Vous pouvez en savoir plus sur l'utilisation de GraphQL ici .

Pour travailler avec GraphQL , à partir de la deuxième version, le paquet gatsby a un composant gatsby qui peut être utilisé à la fois sur les pages et dans des composants simples, et c'est sa principale différence par rapport à sa requête de page précédente. Jusqu'à présent, notre site n'est connecté à aucune source de données, alors essayons d'afficher les métadonnées de la page, par exemple, puis passons à des choses plus complexes.


Pour créer une query vous devez ouvrir http: // localhost: 8000 / ___ graphql , et utiliser la barre latérale avec la documentation pour trouver les données disponibles sur le site, et n'oubliez pas la saisie semi -automatique.


graphql


/src/components/sidebar.js


 import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; export default () => ( <StaticQuery query={graphql` { allSitePage { edges { node { id path } } } } `} render={({ allSitePage: { edges } }) => ( <ul> {edges.map(({ node: { id, path } }) => ( <li key={id}> <Link to={path}>{id}</Link> </li> ))} </ul> )} /> ); 

Maintenant, à l'aide de la query nous obtenons des données sur les pages que nous rendons dans le panneau de navigation, et nous n'avons pas à nous soucier du fait que le lien ne correspondra pas au nom, car toutes les données sont collectées automatiquement.


queried_navigation_panel


En fait, ce sont toutes les données qui peuvent être sur notre site sans utiliser de plug-ins tiers et sans le bon vieux "hardcode", nous passons donc en douceur au sujet suivant de notre article - les plugins.


Plugins


À la base, Gatsby est un compilateur avec un tas de goodies, qui sont des plugins. En les utilisant, vous pouvez personnaliser le traitement de certains fichiers, types de données et différents formats.


Créez le fichier /gatsby-config.js au niveau racine de l'application. qui est responsable de la configuration du compilateur dans son ensemble, et essayez de configurer le premier plugin pour travailler avec des fichiers:


Installation du plugin:


 yarn add gatsby-source-filesystem 

Configuration dans le fichier /gatsby-config.js:


 module.exports = { plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/`, } } ], } 

Plus de détails sur le fichier ci-dessus
  /** * gatsby-config.js     *     JS *     */ module.exports = { /** *  'plugins'  pipeline  * ,      */ plugins: [ /** *        , *         */ `gatsby-example-plugin`, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/`, } } ], } 

Rappelez-vous que nous avons parlé de la «bonne» importation d'images dans Gatsby ?


/src/components/header.js


 import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; export default () => ( <StaticQuery query={graphql` { allFile(filter: { name: { eq: "logo" } }) { edges { node { publicURL } } } } `} render={({ allFile: { edges: [ { node: { publicURL } } ] } }) => ( <header> <Link to="/"> <img src={publicURL} alt="logo" width="60px" height="60px" /> </Link> That is header </header> )} /> ); 

Rien n'a changé sur le site, mais maintenant l'image est substituée à l'aide de GraphQL, au lieu d'une simple importation de webpack. À première vue, il peut sembler que les conceptions sont trop complexes et qu'il s'agissait de gestes inutiles, mais ne nous précipitons pas vers des conclusions, car la chose est dans les mêmes plugins. Par exemple, si nous décidions de publier des milliers de photos sur le site, dans tous les cas, nous devions penser à optimiser le chargement de tout le contenu, et afin de ne pas construire notre processus de chargement paresseux à partir de zéro, nous ajouterions simplement un plugin gatsby-image qui optimiserait le chargement de tous images importées à l'aide d'une query .


Installer des plugins pour le style:


 yarn add gatsby-plugin-typography react-typography typography typography-theme-noriega node-sass gatsby-plugin-sass gatsby-plugin-styled-components styled-components babel-plugin-styled-components 

gatsby-config.js


 module.exports = { plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/` } }, // add style plugins below `gatsby-plugin-typography`, `gatsby-plugin-sass`, `gatsby-plugin-styled-components` ] }; 

Sur le site officiel, vous pouvez trouver un plugin pour tous les goûts.

Style d'application


Commençons à styliser l'application en utilisant différentes approches. Dans l'étape précédente, nous avons déjà installé des plugins pour travailler avec SASS , styled-components et la bibliothèque typography.js , alors qu'il est important de noter que css.modules sont pris en charge dès la sortie de la boîte.


Commençons par les styles globaux qui, comme d'autres choses liées à l'ensemble du site, doivent être configurés dans le fichier /gatsby-browser.js :


 import "./src/styles/global.scss"; 

En savoir plus sur gatsby-browser.js

/src/styles/global.scss


 body { background-color: lavenderblush; } 

Pour diverses raisons, les tendances de ces dernières années penchent vers l'approche "CSS in JS", il ne faut donc pas abuser des styles globaux et il vaut mieux se limiter à indiquer la police et les classes réutilisées. Ce projet particulier prévoit d'utiliser Typography.js à ces fins, donc les styles globaux resteront vides.


Vous avez peut-être remarqué des changements dans l'apparence du site après avoir ajouté gatsby-plugin-typography à la configuration - c'est parce que son préréglage par défaut a été appliqué, et maintenant nous allons le configurer pour nous-mêmes.


/src/utils/typography.js


 import Typography from "typography"; import theme from "typography-theme-noriega"; const typography = new Typography(theme); export default typography; 

Vous pouvez sélectionner n'importe quel autre préréglage dans la liste ou créer le vôtre à l'aide de l'API du package ( exemple de la configuration du site officiel de Gatsby)

/gatsby-config.js


 module.exports = { plugins: [ { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/` } }, { resolve: `gatsby-plugin-typography`, options: { pathToConfigModule: `src/utils/typography` } }, `gatsby-plugin-sass`, `gatsby-plugin-styled-components` ] }; 

Et selon le préréglage sélectionné, le style global du site sera modifié. Décidez quelle approche pour définir des styles globaux pour vous-même, c'est une question de préférences personnelles et de différences d'un point de vue technique, mais nous passons au style des composants en utilisant des composants de style :


Ajouter un fichier avec des variables globales /src/utils/vars.js


 export const colors = { main: `#663399`, second: `#fbfafc`, main50: `rgba(102, 51, 153, 0.5)`, second50: `rgba(251, 250, 252, 0.5)`, textMain: `#000000`, textSecond: `#ffffff`, textBody: `#222222` }; 

/src/components/header.js
  import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; import styled from "styled-components"; import { colors } from "../utils/vars"; const Header = styled.header` width: 100%; height: 3em; display: flex; justify-content: space-between; align-items: center; background-color: ${colors.main}; color: ${colors.textSecond}; padding: 0.5em; `; const Logo = styled.img` border-radius: 50%; height: 100%; `; const logoLink = `height: 100%;`; export default () => ( <StaticQuery query={graphql` { allFile(filter: { name: { eq: "logo" } }) { edges { node { publicURL } } } } `} render={({ allFile: { edges: [ { node: { publicURL } } ] } }) => ( <Header> That is header <Link to="/" css={logoLink}> <Logo src={publicURL} alt="logo" /> </Link> </Header> )} /> ); 

/src/components/sidebar.js
  import React from "react" import { Link, StaticQuery, graphql } from "gatsby" import styled from "styled-components" import { colors } from "../utils/vars" const Sidebar = styled.section` position: fixed; left: 0; width: 20%; height: 100%; display: flex; flex-direction: column; justify-content: center; background-color: ${colors.second}; color: ${colors.textMain}; ` const navItem = ` display: flex; align-items: center; margin: 0 1em 0 2em; padding: 0.5em 0; border-bottom: 0.05em solid ${colors.mainHalf}; postion: relative; color: ${colors.textBody}; text-decoration: none; &:before { content: ''; transition: 0.5s; width: 0.5em; height: 0.5em; position: absolute; left: 0.8em; border-radius: 50%; display: block; background-color: ${colors.main}; transform: scale(0); } &:last-child { border-bottom: none; } &:hover { &:before { transform: scale(1); } } ` export default () => ( <StaticQuery query={graphql` { allSitePage { edges { node { id, path } } } } `} render={({ allSitePage: { edges } }) => ( <Sidebar> { edges.map(({ node: { id, path } }) => ( <Link to={path} key={id} css={navItem} >{id}</Link> )) } </Sidebar> )} /> ) 

stylé


Les éléments déjà existants sont stylisés et il est temps d'associer du contenu à Contentful , de connecter le plugin margin et de générer des pages à l'aide de l' API createPages .


En savoir plus sur la façon de lier Gatsby et Contentful dans un article précédent.

Structure de mes données avec Contentful
  [ { "id": "title", "type": "Symbol" }, { "id": "content", "type": "Text", }, { "id": "link", "type": "Symbol", }, { "id": "orderNumber", "type": "Integer", } ] 

Installation du package:


 yarn add dotenv gatsby-source-contentful gatsby-transformer-remark 

/gatsby-config.js


 if (process.env.NODE_ENV === "development") { require("dotenv").config(); } module.exports = { plugins: [ `gatsby-transformer-remark`, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/`, } }, { resolve: `gatsby-plugin-typography`, options: { pathToConfigModule: `src/utils/typography`, }, }, { resolve: `gatsby-source-contentful`, options: { spaceId: process.env.CONTENTFUL_SPACE_ID, accessToken: process.env.CONTENTFUL_ACCESS_TOKEN, }, }, `gatsby-plugin-sass`, `gatsby-plugin-styled-components`, ], } 

Supprimez le dossier / src / pages avec tous les fichiers à l'intérieur et créez un nouveau fichier pour gérer les nœuds dans Gatsby:


/gatsby-node.js


 const path = require(`path`); /** *  ,      *       */ exports.createPages = ({ graphql, actions }) => { /** *        *        *    */ const { createPage } = actions; return graphql(` { allContentfulArticle { edges { node { title link content { childMarkdownRemark { html } } } } } } `).then(({ data: { allContentfulArticle: { edges } } }) => { /** *       *  createPage()    *      */ edges.forEach(({ node }) => { createPage({ path: node.link, component: path.resolve(`./src/templates/index.js`), context: { slug: node.link } }); }); }); }; 

En savoir plus sur gatsby-node.js

Créez un fichier modèle qui servira de base aux pages générées
/src/templates/index.js


 import React from "react"; import { graphql } from "gatsby"; import Layout from "../components/layout"; export default ({ data: { allContentfulArticle: { edges: [ { node: { content: { childMarkdownRemark: { html } } } } ] } } }) => { return ( <Layout> <div dangerouslySetInnerHTML={{ __html: html }} /> </Layout> ); }; export const query = graphql` query($slug: String!) { allContentfulArticle(filter: { link: { eq: $slug } }) { edges { node { title link content { childMarkdownRemark { html } } } } } } `; 

Pourquoi le <StaticQuery /> n'est-il pas utilisé ici? Le fait est qu'il ne prend pas en charge les variables pour construire une requête, mais nous devons utiliser la variable $slug à partir du contexte de la page.

Mise à jour de la logique dans la barre de navigation
  import React from "react"; import { Link, StaticQuery, graphql } from "gatsby"; import styled from "styled-components"; import { colors } from "../utils/vars"; const Sidebar = styled.section` position: fixed; left: 0; width: 20%; height: 100%; display: flex; flex-direction: column; justify-content: center; background-color: ${colors.second}; color: ${colors.textMain}; `; const navItem = ` display: flex; align-items: center; margin: 0 1em 0 2em; padding: 0.5em 0; border-bottom: 0.05em solid ${colors.main50}; postion: relative; color: ${colors.textBody}; text-decoration: none; &:before { content: ''; transition: 0.5s; width: 0.5em; height: 0.5em; position: absolute; left: 0.8em; border-radius: 50%; display: block; background-color: ${colors.main}; transform: scale(0); } &:last-child { border-bottom: none; } &:hover { &:before { transform: scale(1); } } `; export default () => ( <StaticQuery query={graphql` { allContentfulArticle(sort: { order: ASC, fields: orderNumber }) { edges { node { title link orderNumber } } } } `} render={({ allContentfulArticle: { edges } }) => ( <Sidebar> {edges.map(({ node: { title, link, orderNumber } }) => ( <Link to={link} key={link} css={navItem}> {orderNumber}. {title} </Link> ))} </Sidebar> )} /> ); 

les données


Optimisation SEO


Sur le plan technique, le site peut être considéré comme prêt, alors travaillons avec ses métadonnées. Pour ce faire, nous avons besoin des plugins suivants:


 yarn add gatsby-plugin-react-helmet react-helmet 

react-casque génère <head>...</head> pour les pages HTML et en conjonction avec le rendu Gatsby est un outil puissant et pratique pour travailler avec le référencement.

/src/templates/index.js


 import React from "react"; import { graphql } from "gatsby"; import { Helmet } from "react-helmet"; import Layout from "../components/layout"; export default ({ data: { allContentfulArticle: { edges: [ { node: { title, content: { childMarkdownRemark: { html } } } } ] } } }) => { return ( <Layout> <Helmet> <meta charSet="utf-8" /> <title>{title}</title> </Helmet> <div dangerouslySetInnerHTML={{ __html: html }} /> </Layout> ); }; export const query = graphql` query($slug: String!) { allContentfulArticle(filter: { link: { eq: $slug } }) { edges { node { title link content { childMarkdownRemark { html } } } } } } `; 

Désormais, le title site correspondra toujours au titre de l'article, ce qui affectera considérablement la publication du site dans les résultats de recherche spécifiquement pour ce numéro. Ici, vous pouvez facilement ajouter <meta name="description" content=" "> avec une description de chaque article séparément, permettant ainsi à l'utilisateur de comprendre de quoi parle l'article sur la page de recherche, en général, toutes les fonctionnalités de référencement sont désormais disponibles et gérables un seul endroit.


seo


Configuration PWA


Gatsby est conçu pour offrir des performances de première classe hors de la boîte. Il prend en charge les problèmes de séparation et de minimisation du code, ainsi que l'optimisation sous forme de préchargement en arrière-plan, de traitement d'image, etc., afin que le site que vous créez ait des performances élevées sans aucune configuration manuelle. Ces performances sont un élément important de la prise en charge d'une approche d'application Web progressive.


Mais en plus de tout ce qui précède, il existe trois critères de base pour un site qui le définissent comme PWA :



Le premier point ne peut pas être résolu par Gatsby, car le domaine , l' hébergement et le protocole sont des problèmes de déploiement, et pas du tout de développement, mais je peux recommander Netlify , qui résout le problème https par défaut.


Nous passons aux éléments restants, pour cela nous allons installer deux plugins:


 yarn add gatsby-plugin-manifest gatsby-plugin-offline 

et configurez-les /src/gatsby-config.js


 if (process.env.NODE_ENV === "development") { require("dotenv").config(); } module.exports = { plugins: [ { resolve: `gatsby-plugin-manifest`, options: { name: `GatsbyJS translated tutorial`, short_name: `GatsbyJS tutorial`, start_url: `/`, background_color: `#f7f0eb`, theme_color: `#a2466c`, display: `standalone`, icon: `public/favicon.ico`, include_favicon: true } }, `gatsby-plugin-offline`, `gatsby-transformer-remark`, { resolve: `gatsby-source-filesystem`, options: { name: `images`, path: `${__dirname}/src/images/` } }, { resolve: `gatsby-plugin-typography`, options: { pathToConfigModule: `src/utils/typography` } }, { resolve: `gatsby-source-contentful`, options: { spaceId: process.env.CONTENTFUL_SPACE_ID, accessToken: process.env.CONTENTFUL_ACCESS_TOKEN } }, `gatsby-plugin-sass`, `gatsby-plugin-styled-components`, `gatsby-plugin-react-helmet` ] }; 

Vous pouvez personnaliser votre manifeste à l'aide de la documentation , ainsi que personnaliser la stratégie des techniciens de service en remplaçant les paramètres du plugin .


Vous ne remarquerez aucun changement dans le mode de développement, mais le site répond déjà aux dernières exigences du monde Web, et lorsqu'il sera hébergé sur https: // domaine, il ne sera pas égal.


Conclusion


Il y a quelques années, lorsque j'ai rencontré pour la première fois des problèmes pour mettre l'application React sur Internet, la prendre en charge et mettre à jour le contenu, je ne pouvais pas imaginer qu'il existait déjà une approche JAM-stack sur le marché qui simplifie tous ces processus, et maintenant je ne serai pas surpris. simplicité. Gatsby résout la plupart des problèmes qui affectent les performances du site juste «prêts à l'emploi», et si vous comprenez un peu plus les subtilités de sa personnalisation selon vos besoins, vous pouvez obtenir des indicateurs à 100% pour tous les éléments de Lighthouse , ce qui affecte considérablement la livraison du site dans les moteurs de recherche (par au moins sur Google).


Référentiel avec projet

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


All Articles