Gatsbyの@mosch/gatsby-source-githubでGitHubリポジトリの情報を取得する
Gatsbyを使いこなすには、data-sourceプラグインをどれだけ知っている / 使えるかが鍵かなと思います。ということで、今後お世話になりそうなsource pluginをいろいろ触ってみることにしました。 今回 […]
目次
Gatsbyを使いこなすには、data-sourceプラグインをどれだけ知っている / 使えるかが鍵かなと思います。ということで、今後お世話になりそうなsource pluginをいろいろ触ってみることにしました。
今回はGitHubリポジトリのデータを取得する@mosch/gatsby-source-github
です。
gatsby-source-github-repoも試そうとしたのですが、こちらはnpmから消えている様子です。
install
いつも通りnpmから落としてきましょう。
$ yarn add gatsby-source-github-repo
gatsby-config.jsで取得するリポジトリを指定
リポジトリの指定はconfig側で行います。
{
resolve: `@mosch/gatsby-source-github`,
options: {
repository: "react-sel",
tree: true,
releases: true,
user: "hideokamoto",
}
}
ドキュメントにはtokenの記載がありますが、なくてもpublicリポジトリはいけるみたいです。
おそらくprivateリポジトリへのアクセスやAPIのスロットリング対策で必要なのではないかと思います。
GraphQLクエリをつくる
yarn develop
でGraphiQLを開いてクエリを作りましょう。このプラグインでは、「GitHubリポジトリのファイルを取得できるGitHubFiles」と「GitHubリポジトリで作成したRelease情報を取得できるGithubRelease」の2種類があります。
Markdownファイル系のみ取得するクエリのサンプル
query LIST_MARKDOWN_FILES {
allGithubFile(filter: {path: {regex: "/.md$/"}}) {
edges {
node {
repository
content
path
}
}
}
}
Release情報を取得するクエリのサンプル
query LIST_GH_RELEASES {
allGithubRelease {
edges {
node {
id
name
prerelease
htmlUrl
publishedAt
body
zipballUrl
}
}
}
}
Reactで表示する
Markdownファイルを表示するコンポーネントサンプル
unified
/ remark-parse
/ remark-react
を追加して、Markdownファイルの内容をそのまま描画したコンポーネントです。
import * as React from 'react'
import {useStaticQuery, graphql, Link } from 'gatsby'
import * as unified from 'unified'
import * as parse from 'remark-parse'
const remark2react = require('remark-react')
type AllGithubFileQuery = {
allGithubFile: {
edges: {
node: {
repository: string;
content: string;
path: string;
}
}[]
}
}
const useAllGithubFile = () => {
const {
allGithubFile: {
edges
}
} = useStaticQuery<AllGithubFileQuery>(graphql`query LIST_MARKDOWN_FILES {
allGithubFile(filter: {path: {regex: "/.md$/"}}) {
edges {
node {
repository
content
path
}
}
}
}`)
return edges
}
export const ListGitHubDocumentFiles: React.FC = () => {
const edges = useAllGithubFile()
return (
<>
<h1>Documents</h1>
<dl>
{edges.map(({node}) => (
<React.Fragment key={node.path}>
<dt>{node.path}</dt>
<dd>
{
unified()
.use(parse)
.use(remark2react)
.processSync(node.content)
.result
}
</dd>
</React.Fragment>
))}
</dl>
</>
)
}
描画するとこのようになります。
実際に使う場合は、githubFile
クエリの方で個別にuseStaticQuery
する形の方が現実的かもしれません。
Releaseを表示するコンポーネントサンプル
続いてReleaseを表示するサンプルです。
import * as React from 'react'
import {useStaticQuery, graphql, Link } from 'gatsby'
import * as unified from 'unified'
import * as parse from 'remark-parse'
const remark2react = require('remark-react')
type AllGithubReleaseQuery = {
allGithubRelease: {
edges: {
node: {
id: string;
name: string;
prerelease: boolean;
htmlUrl: string;
publishedAt: string;
body: string;
zipballUrl: string;
}
}[]
}
}
const useAllGithubRelease = () => {
const {
allGithubRelease: {
edges
}
} = useStaticQuery<AllGithubReleaseQuery>(graphql`query LIST_RELEASES {
allGithubRelease {
edges {
node {
id
name
prerelease
htmlUrl
publishedAt
body
zipballUrl
}
}
}
}`)
return edges
}
export const ListGitHubReleases: React.FC = () => {
const edges = useAllGithubRelease()
return (
<>
<h1>Releases</h1>
<pre><code>{JSON.stringify(edges,null,2)}</code></pre>
<ul>
{edges.map(({node}) => (
<li key={node.id}>
<h2>{node.name}</h2>
<dl>
<dt>Published at</dt>
<dd>{new Date(node.publishedAt).toLocaleDateString()}</dd>
<dt>Download</dt>
<dd><a href={node.zipballUrl}>ZIP file</a></dd>
</dl>
{
unified()
.use(parse)
.use(remark2react)
.processSync(node.body)
.result
}
</li>
))}
</ul>
</>
)
}
zipballUrl
のURLにそのままアクセスすると、ZIPファイルのダウンロードができますので、配布等にも使えそうです。
使い所
これもGitHubで公開・配布している系のツールサイトに使えそうです。
ReadmeやChangelogなどのMarkdownで書かれがちなファイルの表示方法が以下の2パターン考えられます。
- allGihubFilesクエリの
regex
でまとめて取得し、gatsby-node.js
で動的にページ生成 githubFiles
クエリで表示したいファイルを個別指定し、pages
にファイル配置 +useStaticQuery
で表示
GitHub Actionsなどで、Releaseをpublishした際にNetlify / Vercel / AWS Amplify Consoleなどのビルドを実行させるように設定することで、ある程度GitHub側の更新にも自動で追従させられるのではないかと思います。