Gatsbyを学ぶ

下記を参考に。
- Gatsby JS - The Great Gatsby Bootcamp [Full Tutorial]
- Gatsbyを最速で理解するためのチュートリアル
- 初心者目線でGraphQLを解説!~同じWebAPIのRESTとの違いは?~
- GraphQL(クエリ言語について)
作業時間:12時間 経過時間:44時間
Gatsby.js×Contentful×Netlifyの構成に変更した。 振り返り。
GraphQLとは
RESTとは、どう違うのか。 RESTはアーキテクチャ、設計、考え方。
- アドレス指定可能
- インターフェースの統一(CRUD)
- ステートレス(状態を保持しない)
- 結果がステータスコードで返される
- and more...
GraphQLはクエリ言語とスキーマ言語から成る。 エンドポイントは1つ。 必要なデータだけをリクエストしレスポンスできる。 ※SQL(構造化問い合わせ言語)はDBに対して問い合わせる、GraphQLはAPIに対して問い合わせる言語。
githubで検証できる。 https://developer.github.com/v4/explorer/
query
例えば、以下。 リクエストの構造がサービスやプロジェクトによって変化する。 viewerをオブジェクト、nameをフィールドと呼ぶ。
//リクエスト
{
viewer {
name
}
}
//レスポンス
{
"data": {
"viewer": {
"name": "sugi"
}
}
}
データを特定の項目でフィルタする場合は、以下のようにフィールドに対して引数を指定する。
//リクエスト
{
viewer {
name
repository(name: "blog") {
id
}
}
}
//レスポンス
{
"data": {
"viewer": {
"name": "sugi",
"repository": {
"id": "MDEwOlJlcG9zaXRvcnkyNzE0NDQ4Mzc="
}
}
}
}
$で変数を渡せることを定義。!は引数が必須であることを明示する。
query ($organization: String!) {
organization(login: $organization) {
name
url
}
}
クエリに名前をつけられる。「オペレーションタイプ」、「オペレーションネーム」と呼ばれる。
query test{
organization(login: $organization) {
name
url
}
}
ディレクティブ @include,@skipで特定のフィールドの取得を操作できる
mutation
データの更新をさせたい場合に使用する。
プラグイン
公式でたくさん紹介されていた。今回利用したものを抜粋。
gatsby-plugin-postcss
postcssをgatsbyで扱うのに使用、postcssはtailwindcssを使用するために使いたかった。
gatsby-transformer-remark
contentfulを使用していて、markdownを使っていたが、htmlに置き換える必要があったので利用。
gatsby-remark-prismjs
markdownの中でハイライトしたいコードがあったので、導入。
gatsby-plugin-react-helmet
title要素を操作するために、導入。
構成
動画を見つつ作成した、最終的な構成は以下。 ※一部のファイルは省略。
├──src
│ ├── components
│ │ ├── footer.js
│ │ ├── head.js
│ │ ├── header.js
│ │ └── layout.js
│ ├── pages
│ │ ├── 404.js
│ │ ├── blog.js
│ │ └── index.js
│ ├── styles
│ │ └── tailwind.css
│ └── templates
│ └── blog.js
│
├──.env
├──.gatsby-config.js
├──.gatsby-node.js
├──postcss.config.js
└──tailwind.config.js
ルーティング
contentfulとgatsbyのファイルの照合の仕組み。
contentfulで定義したslugをもとに、gatsbyのどのファイルでレンダリングするかを決めて行う。.gatsby-node.jsが担当している。module.exports.createPages
で作成。
graphqlを使用して、contentfulのスラッグの値を取得、createPageでファイル、パス、コンテキスト等を指定する。
localhost://8000/___graphql
でテストできる。
.envで以下を定義すると、上記のUIが変わる。
GATSBY_GRAPHQL_IDE=playground
左にリクエスト、右にレスポンスが表示される。 左下のQUERY VARIABLUESには、静的なデータを定義して、クエリの変数に渡せる。 例えば、
//QUERY VARIABLUES
{
"slug":"react-study-10"
}
//クエリ:$slugには、react-study-10が渡る。
query($slug: String!){
contentfulBlog(slug: {eq: $slug}){
title
createdAt(formatString:"MMMM Do, YYYY")
main{
childMarkdownRemark {
html
}
}
}
}
//gatsby-node.js
module.exports.createPages = async({graphql,actions}) => {
const {createPage} = actions
const blogTemplate = path.resolve('./src/templates/blog.js')
const res = await graphql(`
query {
allContentfulBlog {
edges {
node {
slug
}
}
}
}
`)
res.data.allContentfulBlog.edges.forEach(edge => {
createPage({
component: blogTemplate, //レンダリングするファイル指定
path: `/blog/${edge.node.slug}`, //レンダリングするパス指定
context: { //レンダリングするファイル内でアクセスしたいオブジェクトを指定
slug: edge.node.slug,
}
})
});
}
1ファイルにつき、1クエリの定義。queryの結果がdataに渡る。
//templates/blog.js
...
export const query = graphql`
query($slug: String){
contentfulBlog(slug: {eq: $slug}){
title
createdAt(formatString:"MMMM Do, YYYY")
main{
childMarkdownRemark {
html
}
}
}
}
`
const Blog = props => {
return (
<Layout>
<Head title={props.data.contentfulBlog.title} />
<h1>{props.data.contentfulBlog.title}</h1>
<p>{props.data.contentfulBlog.createdAt}</p>
<div
className="body"
dangerouslySetInnerHTML={{
__html: props.data.contentfulBlog.main.childMarkdownRemark.html,
}}
/>
</Layout>
)
}
困ったところ
env-cmd
動画にはなかったが、オプションの指定が必要だった。
最初は以下との指定だった。
env-cmd .env gatsby develop
正しくは以下の指定だった。
env-cmd -f .env gatsby develop
pathのエラー
graphqlでブログ詳細ページの動的レンダリングをスムーズに出来なかった。 プレイグランドでは、レスポンスが返されたので、nodeに問題がありそうな気はした。 エラーは以下が返されていた。
Error: TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
調べた感じでは、たしかにnodeに関連する情報が出たが、今回の事象と結び付けられなかった。
とりあえず以下のプラグインを使用しなくなったので、 アンインストールしてdevelopしたら上手くいってしまった。 関連性が分からない。。
//gatsby-config.js
...
plugins: [
'gatsby-plugin-sharp',
{
options: {
plugins: [
'gatsby-remark-relative-images',
{
resolve: 'gatsby-remark-images',
options: {
maxWidth: 750,
linkImagesToOriginal: false
}
},
...
}
]
作業環境
解決していない。 ローカル環境が異様に遅いのどうにかならないかな。。
次回
テストやhookとかあるけど、reduxやるか。