エンジニアを目指す日常ブログ

日々勉強したことのメモ。独学ですので間違っていたらコメント等で教えてください。

Vagrant環境とのファイル共有がうまくいかないときにやったことメモ

はじめに

Vagrant環境と、ローカル環境ではフォルダを共有することができる。

Vagrantfileに設定を入れてもうまくいかなかったので、原因を探した。 結論としてはvagrant-vbguestをアンインストールすることで解決した。

詳細をメモしておく。

記事の移行

本記事はこちらに移行しました。 bunsugi.com

ssh接続コマンドを簡単に書く方法

はじめに

ssh接続は一般的に

> ssh [SSH先のユーザ名]@[パブリックIP] -i [秘密鍵ファイル(.pem)のパス]

のコマンドで実施するが、事前に.ssh\configファイルを作成し設定を記入しておくことで、

> ssh vagrant

のように、自分でつけた名前を指定してSSH接続することができる。

.ssh\configファイル

C:\Users\[User名]\.ssh\configSSHの情報を記載しておくことができる。

このファイルで、「名前」と「設定値」をセットで管理しておけば、「名前」を使ってSSH接続が可能である。

Vagrantの場合は、> vagrant ssh-configで取得してきた情報をそのまま記載すればよい。

C:\Users\[User名]\.ssh\config

Host aws ←自分でつけた名前
  HostName xx.xxx.xxx.xxx
  User ec2-user
  IdentityFile C:\Users\xxxxxx\xxxxx.pem

Host vagrant ←自分でつけた名前
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile C:/Users/User/vagrant/ubuntu64_18/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

ssh接続コマンド

以下コマンドで接続できる。

> ssh vagrant

おわりに

SSHの設定ファイルと、設定ファイルを利用したSSH接続について記載した。

ゲストOS(Vagrant)とホストOS(Windows)間でscpによりデータをやり取りするコマンドメモ

はじめに

違うサーバどうしでファイルをやり取りするのはscpコマンドが一般的である。

ここでは、scpの基本コマンドの解説に加え、Vagrant仮想環境とローカルのファイルのやり取りを実例としてメモする。

一般的な方法と、

> scp -r -P 2222 -i  【秘密鍵の場所(ローカル)】 vagrant@127.0.0.1:/home/vagrant/workspace/tmp/ ./

簡単な方法を解説する。

scp -r vagrant:/home/vagrant/workspace/tmp/  ./

実施した環境

Vagrant環境からローカルにファイルをコピーする(基本コマンド編)

Vagrant環境の/home/vagrant/workspace/tmp/フォルダから、ローカルのカレントフォルダにファイルをコピーするコマンドは以下となる。

PowerShellで実行する。

> scp -r -P 2222 -i  【秘密鍵の場所(ローカル)】 vagrant@127.0.0.1:/home/vagrant/workspace/tmp/ ./

コマンドの解説

基本コマンドは以下。

$ scp 【コピー元】 【コピー先】

重要なオプションとしては、

  • -P:ポートを指定する
  • -r :ファイルではなくフォルダごとコピーする
  • -issh接続時に使う秘密鍵を指定する

がある。

また、コピー元となるVagrant環境のフォルダ指定は、

【ユーザ名】@【IPアドレス】:【パス】

とする。

ここで、

を調べる必要がある。調べるコマンドは以下。

> vagrant ssh-config
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  (省略)

もっと簡単なコマンドでscpする方法

C:\Users\[User名]\.ssh\configSSHの情報を記載しておくことができる。

このファイルで、「名前」と「設定値」をセットで管理しておけば、「名前」を使ってscpが可能である。

.ssh\configの設定内容

Vagrantの場合は、> vagrant ssh-configで取得してきた情報をそのまま記載すればよい。

外部のサーバでも同様に記載が可能である。

C:\Users\[User名]\.ssh\config

Host aws
  HostName xx.xxx.xxx.xxx
  User ec2-user
  IdentityFile C:\Users\xxxxxx\xxxxx.pem

Host vagrant
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile C:/Users/User/vagrant/ubuntu64_18/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL

私の場合はvagrantAWS-EC2の設定が入っている。

tomiko0404.hatenablog.com
こちらの記事で、VSCode用に設定していた。

scpコマンド

上記.ssh\configvagrantという名前を付けている設定値を使いたい。

コマンドは以下のようになる。

 scp -r vagrant:/home/vagrant/workspace/tmp/  ./

おわりに

scpコマンドを使ってサーバ間でデータをやりとりすることができた。

Ubuntu + Vagrant + VirtualBox環境でディスク容量を拡張した

はじめに

VirtualBoxで突然以下のようなエラーが発生。

npm ERR! code ENOSPC
npm ERR! syscall write
npm ERR! errno -28
npm ERR! nospc ENOSPC: no space left on device, write
npm ERR! nospc There appears to be insufficient space on your system to finish.
npm ERR! nospc Clear up some disk space and try again.

不要ファイルを削除してお茶を濁してみたが、いよいよ壊れ始めたので、仮想環境のディスク容量拡張に挑戦した。

Qiitaを探すとCentOSのやり方がヒットするのだが、Ubuntuの場合やり方が若干違うようだ。

最後は自己流になってしまうなど、かなり苦労した。

前提

  • Windows環境の上に、VirtualBox + Vagrant で構築したLinux環境を利用。
  • React.jsのGatsbyモジュールを使ったアプリを開発していた時に起こった。
  • OSはubuntuを利用。
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:        18.04
Codename:       bionic

エラー原因の確認:ディスク容量不足

このエラー発生時は、ディスク容量が足りない可能性が高い。 参考にした記事では、innodeが足りなかったとのこと。

参考: No space left on device とエラーが出るときの対処法 - Qiita 自分の環境でたたいてみると、ディスク容量が足りないことが分かった。

$ df -hP
Filesystem              Size  Used Avail Use% Mounted on
udev                    1.5G     0  1.5G   0% /dev
tmpfs                   299M  640K  299M   1% /run
/dev/sda1               9.7G  9.7G     0 100% /
tmpfs                   1.5G     0  1.5G   0% /dev/shm
tmpfs                   5.0M     0  5.0M   0% /run/lock
tmpfs                   1.5G     0  1.5G   0% /sys/fs/cgroup
vagrant                 238G  199G   39G  84% /vagrant
home_vagrant_workspace  238G  199G   39G  84% /home/vagrant/workspace
tmpfs                   299M     0  299M   0% /run/user/1000

/dev/sda1というのは、10GBであることからおそらくVirtualBoxのメインストレージ。

VirtualBoxマネージャー画面
VirtualBoxマネージャー画面

ディスク拡張のやりかた

ディスク拡張プラグインのインストール

ホストOS(Windows)上で、vagrant-disksizeプラグインをインストールする。

> vagrant plugin install vagrant-disksize

Vagrantfile追記

Vagrantfileに以下を追記する。

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"0
  config.disksize.size = "20GB"   # この行を追記
end

VagrantFile全体は以下のようになる。

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"
  config.disksize.size = "20GB"
  config.vm.network "forwarded_port", guest: 8000, host: 8000
  config.vm.network "forwarded_port", guest: 3000, host: 3000
  config.vm.synced_folder "./workspace", "/home/vagrant/workspace"
  config.vm.provider :virtualbox do |vb|
    vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/home/vagrant/workspace","1"]
  end

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
  end

end

Vagrantを再起動する

Vagrantを再起動する。

> vagrant halt
> vagrant up

再起動時、以下のようなログが出ていれば成功。

==> default: Resized disk: old 10240 MB, req 20480 MB, new 20480 MB

ディスク容量の確認

VirtualBoxマネージャーの表示は変わっている。

VirtualBoxマネージャー
VirtualBoxマネージャー

パーティションを管理するfdiskというコマンドを使うと、

$ sudo fdisk -l
Disk /dev/sda: 20 GiB, 21474836480 bytes, 41943040 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x20027de7

Device     Boot Start      End  Sectors Size Id Type
/dev/sda1  *     2048 20971486 20969439  10G 83 Linux

ディスク容量はDisk /dev/sda: 20 GiBと増えているが、パーティションの領域は

Device     Boot Start      End  Sectors Size Id Type
/dev/sda1  *     2048 20971486 20969439  10G 83 Linux

であり、増えていないことがわかる。

dfコマンドで確認しても増えていなかった。

$ df -hP
Filesystem              Size  Used Avail Use% Mounted on
udev                    984M     0  984M   0% /dev
tmpfs                   200M  5.6M  194M   3% /run
/dev/sda1               9.7G  9.7G     0 100% /   ★まだ変わっていない
tmpfs                   997M     0  997M   0% /dev/shm
tmpfs                   5.0M     0  5.0M   0% /run/lock
tmpfs                   997M     0  997M   0% /sys/fs/cgroup
vagrant                 238G  200G   38G  85% /vagrant
home_vagrant_workspace  238G  200G   38G  85% /home/vagrant/workspace
tmpfs                   200M     0  200M   0% /run/user/1000

パーティションの領域拡張

partedというコマンドを使う。fdiskと同じくパーティションを追加したり削除したりするコマンド。

$ sudo parted

と入力し、

print free

と入力すると現在の状況を確認できる。

(parted) print free
Model: VBOX HARDDISK (scsi)
Disk /dev/sda: 21.5GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:

Number  Start   End     Size    Type     File system  Flags
        32.3kB  1049kB  1016kB           Free Space
 1      1049kB  10.7GB  10.7GB  primary  ext4         boot
        10.7GB  21.5GB  10.7GB           Free Space

Number1のパーテーション(おそらく、/dev/sda1に対応する)の後ろがFree Spaceとなっているため、1番を後ろに拡張できそう。

パーティションを拡張するイメージ
パーティションを拡張するイメージ

そこで、

resizepart 1

と入力し、

Warning: Partition /dev/sda1 is being used. Are you sure you want to continue?
Yes/No? y

「使っているけど続行する?」の問いにはyを回答する。

次に容量を聞かれるので、21.5GBと入力する。

End?  [10.7GB]? 21.5GB

ここまで行ったらpartedを抜けてよい。

(parted) ^C

Vagrant再起動、容量の確認

Vagrantを再起動して、容量を確認すると

$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            984M     0  984M   0% /dev
tmpfs           200M  620K  199M   1% /run
/dev/sda1        20G  9.7G  9.7G  50% /   ★できた!!
tmpfs           997M     0  997M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           997M     0  997M   0% /sys/fs/cgroup
tmpfs           200M     0  200M   0% /run/user/1000

容量が20GBになっていることが確認できた。

ファイルシステムの拡張が必要な場合がある?

参考文献では、resize2fsコマンドを利用してファイルシステムを拡張していた。

sudo resize2fs /dev/sda1

今回は不要だったが、念のためメモしておく。

参考資料

www.xenos.jp

参考:試してみてダメだった方法

最初は、以下ページを参考に、

  • パーティション新規作成
  • 物理ボリューム作成
  • 物理ボリュームを既存のボリュームグループに割り当てる
  • ボリュームグループに対応する論理ボリュームを拡張
  • ファイルシステムの拡張

という手順を実行しようと試みた。

VagrantのCentOSのディスク容量を増やす手順 - Qiita

物理ボリューム、ボリュームグループ、論理ボリュームの概念は以下を参照。

suzuki-kengo.net

ただ、そもそも私の環境にはボリュームグループというものが存在せず、新規作成した物理ボリュームをマウントする方法がわからなかった。

以下ページによると、UbuntuではCentOSと違い、LVMが利用されていないらしい。

技術メモメモ: Ubuntu 20.04でシステム領域のディスク容量の拡張を行う

おわりに

UbuntuVagrantVirtualBoxの環境で、ディスク容量を拡張することができた。 Linuxの勉強をまったくできておらず、パーティションの概念も初めて知った。勉強不足がつらい。

VirtualBoxの容量不足エラーが出たときにやったことメモ

はじめに

VirtualBoxで突然以下のようなエラーが発生。

npm ERR! code ENOSPC
npm ERR! syscall write
npm ERR! errno -28
npm ERR! nospc ENOSPC: no space left on device, write
npm ERR! nospc There appears to be insufficient space on your system to finish.
npm ERR! nospc Clear up some disk space and try again.

容量が足りないエラーのようで、不要ファイルを削除することで解消した。 実施したことをメモする。

追記

本記事を書いた数時間後に再度同じエラーが発生、どうしようもなくなったため容量拡張を実施した。 あくまで本記事は暫定対応と考えたほうがよい。

前提

  • Windows環境の上に、VirtualBox + Vagrant で構築したLinux環境を利用。
  • React.jsのGatsbyモジュールを使ったアプリを開発していた時に起こった。
  • OSはubuntuを利用。
Distributor ID: Ubuntu
Description:    Ubuntu 18.04.4 LTS
Release:        18.04
Codename:       bionic

原因の確認→ディスク容量不足

このエラー発生時は、ディスク容量が足りない可能性が高い。 参考にした記事では、innodeが足りなかったとのこと。

参考: No space left on device とエラーが出るときの対処法 - Qiita 自分の環境でたたいてみると、ディスク容量が足りないことが分かった。

$ df -hP
Filesystem              Size  Used Avail Use% Mounted on
udev                    1.5G     0  1.5G   0% /dev
tmpfs                   299M  640K  299M   1% /run
/dev/sda1               9.7G  9.7G     0 100% /
tmpfs                   1.5G     0  1.5G   0% /dev/shm
tmpfs                   5.0M     0  5.0M   0% /run/lock
tmpfs                   1.5G     0  1.5G   0% /sys/fs/cgroup
vagrant                 238G  199G   39G  84% /vagrant
home_vagrant_workspace  238G  199G   39G  84% /home/vagrant/workspace
tmpfs                   299M     0  299M   0% /run/user/1000

/dev/sda1というのは、10GBであることからおそらくVirtualBoxのメインストレージ。

VirtualBoxマネージャー画面
VirtualBoxマネージャー画面

ディスク容量をひっ迫しているフォルダの確認

ルートディレクトリ配下のフォルダごとのデータ量を確認する。

ルートフォルダに移動して中身の確認。

$ cd /
$ sudo du -sh ./*/
8.1G    ./home/
...省略...

ホームディレクトリが圧倒的に大きいことが分かった。

ホームディレクトリの中のvagrant(ユーザ名)ディレクトリに移動して、隠しファイル以外のデータ量を確認する。

$ cd home/vagrant
$ sudo du -sh ./*/
161M    ./aws/
753M    ./gatsby/
4.0K    ./tmp/
2.5G    ./workspace/

これだけでは8.1GBに達する理由がわからないため、隠しフォルダのデータ量も確認。

$ du -scmh ./.[^.]* | sort -rh
4.7G    total
1.3G    ./.nvm
1.3G    ./.cache
1.1G    ./.npm
939M    ./.vscode-server
116M    ./.config
5.2M    ./.yarn
...省略...

参考: duでカレントディレクトリ以下の使用容量をパッと見たいとき用のコマンド 隠しファイルも - Qiita

1.3G    ./.nvm
1.3G    ./.cache
1.1G    ./.npm

このあたりの容量が大きそうだが、nvmnpmは消したらまずい気がしたのでcacheをターゲットにする。

キャッシュフォルダの中身確認

./.cacheフォルダの中身を確認する。

$ cd ./.cache
$ sudo du -sh ./*/
109M    ./typescript/
1.2G    ./yarn/

どうやら./yarnフォルダが容量を食っている模様。

yarnのキャッシュを消してよいのか調査

home/.cache/yarnフォルダを消して問題が起きないか自信が無い(さすがにキャッシュだから大丈夫だとは思うが)ので少し調べたところ、以下の記事で気軽にキャッシュをクリアしていたので、問題ないと信じることにした。

参考: 【yarn install】ハマったときの解決方法

どのプロジェクトで使われているフォルダなのか

作業していたGatsby.jsのプロジェクトフォルダに移動して、yarnのキャッシュ保管フォルダを確認すると、まさに問題になっていたフォルダだった。

$ cd gatsby-starter-blog/
$ yarn cache dir
/home/vagrant/.cache/yarn/v6

参考: yarnのキャッシュを理解してnode_modulesを正しく更新する - さかなソフトブログ

このまま

$ yarn cache clean

を実施したところ、データ量が1GBほど削減された。

VartualBox再起動

再起動すると、Linuxの操作が再びできるようになった。

vagrant halt
vagrant up

おわりに

VirtualBoxの容量不足エラーを、キャッシュを削除することで回避できた。

ただし、本来はVirtualBoxへの割り当て容量を増やすほうが良いと思う。

また、本当に容量が足りなくなるとvagrant upすらできなくなるので、詰む可能性あり。 私はwindowsと共有しているフォルダから適当なファイルを手動で削除することで、起動できた。

【Gatsby】マークダウンファイルから記事ページを生成する

はじめに

前回、マークダウンのファイル情報をデータレイヤに取り込み、ブログ上に表示することができた。

今回はブログ記事ページを動的に作成する。

方法としては、

がありそう。

今回はテンプレートコンポーネントを作成する方法を利用する。

本記事のゴール

  • ブログ記事ページのテンプレートを作成する。
  • 開発環境に保存したマークダウン形式の記事の中身と、テンプレートから、記事ごとのページを自動で生成する。

前回の記事

tomiko0404.hatenablog.com

前提

  • gatsby-starter-blogスターターキットを利用したgatsbyブログを立ち上げ済
  • Vagrantを開発環境として利用
  • Gatsby Cloudで公開済(今回は利用しないので、なくても可)
  • gatsby-source-filesystemの設定が完了し、/content/blogフォルダ内のファイルがデータレイヤーに読み込まれる状態になっている
  • gatsby-plugin-mdxの設定が完了し、ファイルをMDXファイルとして利用できる状態になっている

参考にしたサイト

www.gatsbyjs.com

テンプレートとマークダウンから動的にページを作成する流れ

  1. マークダウンファイルを作成する
  2. テンプレートコンポーネントを作成する
  3. テンプレートコンポーネント内で、特定の(URLに対応する)マークダウンから情報を読み込むソースコードを記述する
  4. ビルドする

マークダウンファイルを作成する

前回の記事を参考に、MDXファイルを作成する。

content/blog/mdx-content.mdx

---
title: "mdxで記事を書いてみる"
date: "2022-02-26"
---

## はじめに
記事の内容

テンプレートコンポーネントを作成する

テンプレートコンポーネントを作成する。

作成する場所

pages配下の、URLに対応する場所に作成する。

例えば、ブログ記事ページのURLを~~~~.com/blog/記事名にしたい場合、テンプレートコンポーネントsrc/pages/blog/配下に作成する。

コンポーネントのファイル名

{mdx.slug.js}とする。

構文としては

{{データレイヤのノード名}.{URLに利用したいフィールド名}.js}

となる。

今回は、mdxノードを利用し、URLにはslugフィールドを利用するので{mdx.slug.js}となる。

別のフィールドを使いたい場合

{URLに利用したいフィールド名}が深い場所にある場合は、__(アンダーバー2つ)でネストして行ける。(例:{mdx.frontmatter__slug}.js

slugフィールドとは

gatsby-plugin-mdxを使ってMDXノードに変換すると、自動的にslugフィールドが生成される。これをURLに利用するとよい。

slugフィールド
slugフィールド

自分でslugを設定する

MDXファイル内に自分でslugフィールドを作成し、ファイル名を

{mdx.frontmatter__slug}.js

とすると、ファイル名とは別に好きなURLにすることができる。

---
title: "mdxで記事を書いてみる2"
slug: "mdx-content-my-slug"
date: "2022-03-07"
---

## はじめに

テンプレートの中身を記載する

テンプレートコンポーネント内で、特定の(URLに対応する)マークダウンから情報を読み込むソースコードを記述する。

クエリの作成

クエリはテンプレートコンポーネントに以下のように記載する。

export const query = graphql`
query ($id: String) {
    allMdx(filter: {id: {eq: $id}}) {
      nodes {
        body
        slug
        frontmatter {
          date(formatString: "MMMM D, YYYY")
          title
        }
      }
    }
  }
`
query ($id: String)

は、id変数を引数として利用するという宣言。

allMdx(filter: {id: {eq: $id}}) {

は、idフィールドが$idと等しいもののみ抽出するという指定。

参考:変数を引数としてクエリに設定する方法のメモ tomiko0404.hatenablog.com

変数に入れる値の取得方法

クエリえMDXノードの情報を取得する際に「どのページか」を判定する必要がある。

Gatsbyでは、ページテンプレートコンポーネントを使って作られたページにおいて、props.pageContextの中に、MDXノードを一意に特定するidの値が初めから入っているためこれを利用する。

props.pageContextにはidと、URLに利用したいフィールド名(ここではslug)が自動で渡される。

以下ページによると、ページ生成時にprops.pageContextとして渡された値はGraphQLの引数としてそのまま利用できる。

// Add optional context data to be inserted
// as props into the page component.
//
// The context data can also be used as
// arguments to the page GraphQL query.
//
// The page "path" is always available as a GraphQL
// argument.
Gatsby Node APIs | Gatsby

そのため、前節のクエリを記載するだけで、ページに特有のidをフィルタ条件として利用してくれる。

pageContextについては勉強不足のため割愛する。

テンプレートコンポーネントソースコード

全体としてソースコードは以下のようになる。

src/pages/blog/{mdx.slug}.js

import { graphql } from 'gatsby';
import { MDXRenderer } from 'gatsby-plugin-mdx';
import * as React from 'react';
import MyLayout from '../../components/myLayout';


const BlogPost = (props) => {
    console.log(props);
    const {data} = props;
    return (
        <MyLayout pageTitle="Super Cool Blog Posts">
            <MDXRenderer>
                {data.allMdx.nodes[0].body}
            </MDXRenderer>
        </MyLayout>
    )
}


export const query = graphql`
query ($id: String) {
    allMdx(filter: {id: {eq: $id}}) {
      nodes {
        body
        slug
        id
        frontmatter {
          date(formatString: "MMMM D, YYYY")
          title
        }
      }
    }
  }
`

export default BlogPost

今回は勉強の流れでallMdxフィールドを利用し、idを指定することで要素数1の配列を取得・表示している。

1件のMDXノード情報だけ取れればよいので、mdxフィールドを利用するのがよさそう。

おわりに

テンプレートコンポーネントを作成して、ブログ記事ページを自動で生成することができた。

GraphQLの引数を変数で設定する方法のメモ

はじめに

GraphQLのリクエストに引数を入れる際、引数を固定値ではなく変数で設定するやり方をメモ。

GraphQLとは/基本的なリクエストの書き方

以下の記事を参照。 tomiko0404.hatenablog.com

引数なしのリクエス

リクエスト(すべてのMDXノードのslug(ファイル名)フィールドとidフィールドを取得)

query {
  allMdx {
    nodes {
      slug
      id
    }
  }
}

取得できる値

"data": {
 "allMdx": {
   "nodes": [
     {
       "slug": "mdx-content",
       "id": "c31f21f8-8731-5bc1-b8fa-906aabd57930"
     },
     {
       "slug": "mdx-content2",
       "id": "9ce566d8-ae20-5b54-9d23-424487f61361"
     }
   ]
 }

引数が固定値のリクエス

リクエスト(MDXノードのうちid"9ce566d8-ae20-5b54-9d23-424487f61361"と等しいノードのslug(ファイル名)フィールドとidフィールドを取得)

query {
  allMdx(filter: {id: {eq: "9ce566d8-ae20-5b54-9d23-424487f61361"}}) {
    nodes {
      slug
      id
    }
  }
}

取得できる値

"data": {
  "allMdx": {
    "nodes": [
      {
        "slug": "mdx-content2",
        "id": "9ce566d8-ae20-5b54-9d23-424487f61361"
      }
    ]
  }
}

引数に変数を設定する場合のリクエス

この方法はページクエリでしか利用できない。

useStaticQueryでは利用できないので注意する。

リクエスト(MDXノードのうちidフィールドが変数idと等しいノードのslug(ファイル名)フィールドとidフィールドを取得)

query ($id: String) {
    allMdx(filter: {id: {eq: $id}}) {
      nodes {
        slug
        id
      }
    }
  }

GraphiQL

GraphiQLを使ってリクエストを作成する際は、変数に入る値を仮設定することができる。左下のQUERY VARIABLESにJSON形式で設定する。

GraphiQLでの変数仮設定
GraphiQLでの変数仮設定

Gatsby.jsでの利用

MDX(マークダウン)ファイルの情報が入っているMDXノードの情報を取得するために、テンプレートとなるコンポーネント上でidを指定するクエリが必要である。

Gatsbyでは、ページテンプレートコンポーネントを使って作られたページにおいて、props.pageContextの中に、MDXノードを一意に特定するidの値が初めから入っている。

idを変数として引数に入れておくことで、props.pageContext.idの値をフィルタ条件として利用できる。

{mdx.slug}.js

import { graphql } from 'gatsby';
import { MDXRenderer } from 'gatsby-plugin-mdx';
import * as React from 'react';
import MyLayout from '../../components/myLayout';

const BlogPost = (props) => {
    console.log(props.pageContext.id);
    const { data } = props;
    return (
        <MyLayout pageTitle="Super Cool Blog Posts">
            <MDXRenderer>
                {data.allMdx.nodes[0].body}
            </MDXRenderer>
        </MyLayout>
    )
}

export const query = graphql`
query ($id: String) {
    allMdx(filter: {id: {eq: $id}}) {
      nodes {
        body
        slug
        frontmatter {
          date(formatString: "MMMM D, YYYY")
          title
        }
      }
    }
  }
`

export default BlogPost

pageContextについては勉強不足のため割愛する。

おわりに

GraphQLで引数を利用し、props等から取得した変数を設定する方法をメモした。