Gatsby Internals для разработчиков | Кодементор
Гэтсби отличный инструмент. К сожалению, трудно найти хорошую документацию по
некоторые из очень полезных API-интерфейсов, которые мы можем использовать при создании приложения Gatsby.
Не теряя времени, давайте погрузимся прямо в некоторые интересные открытия.
моего исследования Гэтсби.
Как это работает⚙️? Обзор 🔭
В Gatsby вы пишете шаблоны страниц в JSX и, возможно, вы также предоставляете способ получить динамический контент для страницы. В общем
через ГрафQL Запрос.
Итак, если вы хотите иметь страницу на своем веб-сайте по адресу your-website.com/about.html
вы создадите Реагировать Компонент в src/pages/about.js
import React from 'react'
export default function About() {
return (
<div>
About Me
</div>
)
}
Прямо сейчас здесь просто статический контент, который представляет собой строку About Me
.
Если я хочу сделать эту строку динамической, я могу использовать для этого запрос GraphQL.
import React from 'react'
import { graphql } from 'gatsby'
export default function About({data}) {
return (
<div>
{data.dynamicString}
</div>
)
}
export const query = graphql`
query aboutMeDynamicContent {
# Your GraphQL Query here
}
`
Теперь может показаться, что каждый раз, когда этот компонент загружается, он сначала извлекает данные, а затем отображает их. Что действительно происходит, так это
Gatsby не загружает динамический контент во время выполнения или когда ваш сайт работает. Это делает это только однажды в течение время сборки.
Таким образом, все запросы или вызовы API, которые вы определяете, вызываются в то время, когда ваш веб-сайт
создается Гэтсби, где он проходит через все определенные вами компоненты и генерирует статический HTML из этих компонентов.
Если компилятор также находит запрос GraphQL, он вызывает эти запросы и сохраняет все данные из них.
запросы и использовать эти данные для создания статический HTML этого компонента страницы. После процесса сборки ваше приложение должно стать полностью статичным, т.е.
данные, которые ему нужны, поэтому ему не нужно запрашивать какое-либо динамическое содержимое во время выполнения.
Гэтсби использует рендеринг на стороне сервера для создания предварительно обработанного SPA, который преобразуется в полнофункциональное приложение React.
Gatsby хранит все данные в большом файле JSON.
Сейчас я не хочу вдаваться в подробности того, как это работает. Есть так много замечательных статей, которые делают потрясающую работу.
описывая одно и то же. Давайте перейдем к некоторым более крутым вещам.
Как это работает⚙️? Взгляд изнутри 🔬
А Узел является основой всех моделей данных, используемых в Gatsby.
type Node = {
id: String,
children: Array[String],
parent: String,
fields: Object,
internal: {
type: String,
...
},
...other fields specific to this type of node
}
Запросы GraphQL, которые мы вводим, нацелены на эти узлы для получения данных.
Чтобы лучше понять процесс создания узла и управления им, давайте
напишите несколько фиктивных плагинов для создания сообщений в блоге из файлов уценки.
Я буду писать псевдокод для некоторой части, чтобы избежать сложности.
Также я буду писать много комментариев для описания различных частей кода. Убедитесь, что вы прочитали их.
Наша структура каталогов выглядит примерно так
content/
my-journey-to-neverland.md
my-new-blog.md
src/
components/
post.js
pages/
index.js
gatsby-node.js
package.json
Шаг 1 — Чтение файлов Markdown 🥔
Мы создадим плагин для этого. Назовем наш плагин my-file-reader
Реализация будет выглядеть примерно так в файле с именем gatsby-node.js
.
function readFile(path){
... read file at path `path`
return {
name,
content,
path,
fileType,
modifiedAt,
createdAt
};
}
exports.sourceNodes = (
{ actions, getNode, createNodeId },
pluginOptions ) => {
const { createNode } = actions;
const fileDirectory = pluginOptions.path;
fileDirectory.forEach((filePath) => {
const file = readFile(filePath);
createNode({
id: createNodeId(),
children: [],
parent: undefined,
internal: {
type: 'MySourceFileNode',
},
name: file.name,
content: file.content,
path: file.path,
fileType: file.fileType,
modifiedAt: file.modifiedAt,
createdAt: file.createdAt
});
});
}
На данный момент мы прочитали наш .md
файлы и проинформировал Гэтсби о наших файловых узлах, сделанных на заказ.
Теперь они будут доступны для наших запросов GraphQL. Гэтсби автоматически создаст
схема GraphQL для нас. Мы можем запросить имя файла, тип файла и все другие свойства, используя GraphQL.
Хорошая новость заключается в том, что вам не нужно писать плагин для чтения простых необработанных файлов. Там
является официальный плагин за это 🤝.
Шаг 2 — Создайте HTML из Markdown 🍟
Теперь, когда у нас есть сырье .md
файлы в нашей системе представлены в виде узлов. Мы создадим
новый тип узла, который будет содержать наш html (после компиляции нашей необработанной уценки в html).
Для этого мы создадим еще один плагин. Назовем наш плагин my-md-transformer
Реализация будет выглядеть примерно так в файле с именем gatsby-node.js
.
const mdToHtml = require('magic-md-to-html-transformer');
function createMDNode({id, node, content}) {
const { html } = mdToHtml(content);
const mdNode = {
id,
children: [],
parent: node.id,
internal: {
content: content,
type: "Md"
}
};
mdNode.html = html;
return mdNode;
}
exports.onCreateNode = async (
{
node,
loadNodeContent,
actions,
createNodeId,
getNode,
},
pluginOptions
) => {
const { createNode, createParentChildLink, createNodeField } = actions;
if (node.internal.type !== "MySourceFileNode") {
return;
}
const content = await loadNodeContent(node);
const mdNode = createMDNode({
id: createNodeId(),
node,
content
});
createNode(mdNode);
createParentChildLink({ parent: node, child: mdNode });
createNodeField({
name: 'slug',
mdNode,
value: kebabCase(node.fileName)
});
}
На данный момент у нас есть готовая html-разметка, сохраненная в наших вновь созданных узлах как свойство.
Следующий шаг — зарегистрировать URL-адреса в gatsby для обслуживания этой разметки.
Хранилище узлов, используемое внутри Гэтсби, будет иметь что-то вроде этого
[
{
id: '123456',
children: ['abc'],
parent: ,
internal: {
type: 'MySourceFileNode',
},
name: 'my-new-blog',
content: '↵# My New Blog↵↵Hello World!',
},
{
id: '7891011',
children: ['ghi'],
parent: ,
internal: {
type: 'MySourceFileNode',
},
name: 'my-journey-to-neverland',
content: '↵# Journey to neverland↵↵Hello World!',
},
{
id: 'abc',
children: [],
parent: '123456',
internal: {
type: 'Md',
},
field: {
slug: 'my-new-blog',
},
html: '<bod><body><h1>My New Blog</h1><p>Hello World!</p></body></html>',
},
{
id: 'ghi',
children: [],
parent: '7891011',
internal: {
type: 'Md',
},
field: {
slug: 'my-journey-to-neverland',
},
html: '<bod><body><h1>Journey to neverland</h1><p>Hello World!</p></body></html>',
}
]
Шаг 3. Подача HTML-страниц 🍽
Теперь мы хотим сказать Gatsby отображать наши блоги по указанным нами URL-адресам.
Gatsby также предоставляет API для этой цели.
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions;
return new Promise((resolve, reject) => {
resolve(
graphql(
`
{
allMd {
#edges is like results
edges {
node {
id
fields {
slug
}
}
}
}
}
`
).then(result => {
if (result.errors) {
console.error(result.errors);
reject(result.errors);
}
const posts = result.data.allMd.edges;
posts.forEach(({ node }, index) => {
createPage({
path: node.fields.slug,
component: path.resolve(__dirname, `src/components/post.js`),
context: {
id: node.id,
}
});
});
})
);
});
};
Вот и все, наши блоги уценки теперь готовы для использования в качестве HTML-страниц. Этот пример
был основан на блогах, присутствующих в нашей файловой системе, но мы можем использовать что угодно в качестве поставщика контента (API, CMS, удаленная файловая система) и создавать контент/страницы.
для нашего сайта. В этом сила Гэтсби.
Мне нравилось исследовать Гэтсби, и это единственная причина, по которой я переписал свой веб-сайт. Если у вас есть какие-либо вопросы относительно этого блога, свяжитесь со мной
в ts17995@gmail.com. Я буду рад ответить.