Search by

    gatsby-source-filesystemについて

    gatsby-source-filesystemについてわかったことまとめてます。

    一言でいうと何?

    • ローカルのファイルシステムと、gatsbyをつなぐインターフェイスになるようなプラグイン。
    • Filenodeをローカルファイルから作成する。
    因みにファイルの中身自体を表示するには??
    • 種々のファイル形式に対応した"transformer"というプラグインがそれぞれ用意されている。
    • "transformer"でFilenodeの中身を取得する。

    インストール

    npm install --save gatsby-source-filesyste

    どのファイルを使うか決める。

    どのディレクトリをnodeに加えるか≒どのディレクトリをインスタンスにするかは gatsby-config.jsで定義する。 (どのファイルをgatsbyに読み込みたいか、をここで定義する。)

    gatsby-config.js
      plugins: [
        'gatsby-plugin-react-helmet',
        'gatsby-plugin-sass',
        {
          resolve: 'gatsby-source-filesystem',
          options: {
            path: `${__dirname}/static/img`,// (例えば)イメージがある場所
            name: 'uploads',
          },
        },
        {
          resolve: 'gatsby-source-filesystem',
          options: {
            path: `${__dirname}/src/pages`,// (例えば).mdがある場所
            name: 'pages',// インスタン名をpagesにする。
          },
        }
      ]
      // etc

    graphQLで使いたいファイルが見えるか確認

    gatsby developで開発用サーバーを起動し、http://localhost:8000/___graphqlにアクセス allFile,fileが追加されたことを確認する。 両者の違いはよくわからないが基本的に前者を使うと思われる。

    graphQLの書き方

    例えばpagesインスタンスの情報(名前とサイズ)を取得するには、下記の様にする。

    query MyQuery {
      allFile(filter: {sourceInstanceName: {eq: "pages"}}) {
        edges {
          node {
            name
            size
          }
        }
      }
    }

    ファイルからslugを作成するまでの流れ

    1. ノード作成時の動きを拡張する。
    2. ノードのパスを取得する。gatsby-source-filesystemがこれを可能にしている。
    3. パスをslugとしてノードに追加する。
    gatsby-node.js
    // エクストラクト
    const { createFilePath } = require(`gatsby-source-filesystem`)
    
    // 渡しているnodeは、gatsby内部のオブジェクト。独自で定義したものを渡すと怒られる。
    exports.onCreateNode = ({ node, getNode, actions }) => {
     
      //アクションオブジェクトからcreateNodeFieldを取り出す。
      const { createNodeField } = actions
    
     // Ensures we are processing only markdown files
      if (node.internal.type === "MarkdownRemark") {
        
        // Use `createFilePath` to turn markdown files in our `data/faqs` directory into `/faqs/slug`
        // `data/faqs`以下のファイル名をパスに変換する。
        const relativeFilePath = createFilePath({
          node,     //何を
          getNode, //どうやって onCreateNodeからのgetNodeをここに渡す。
          basePath: "data/faqs/", //どこから
        })
    
        // Creates new query'able field with name of 'slug'
        // ファイルをslugというnodeとして、作成する。
        createNodeField({
          node,
          name: "slug",
          value: `/faqs${relativeFilePath}`,
        })
      }
    }

    createFilePath

    exsample.com/slugとすることでファイルにアクセスできる。 (slugではなくても、記事を任意に識別できればいいが、id等では人の目で見て、記事を認識できない。 このため、ファイル名をパスにした方がよい。) ので、slugを作りたい。slugを作るにはパスが必要。 gatsby-source-filesystemにはパスを作ってくれるcreateFilePathというヘルパーが用意されている。

    createFilePath({
      // The node you'd like to convert to a path 変換したいファイル
      // e.g. from a markdown, JSON, YAML file, etc
      node:
      // Method used to get a node onCreateNodeからのパラメータはここに渡されねばならない。
      // The parameter from `onCreateNode` should be passed in here
      getNode:
      // The base path for your files.
      // Defaults to `src/pages`. For the example above, you'd use `src/content`.
      basePath:
      // Whether you want your file paths to contain a trailing `/` slash
      // Defaults to true
      trailingSlash:
    })

    まとめ

    • gatsby-source-filesystemはファイル情報をgraphQL扱えるノードに追加する。
    • ノードからファイルパスを取得して、slugにすることで、外部からのアクセスに利用できるようにする。
    • 実際のページを作るにはtransformerプラグインが必要。

    参考

    ES6 object destructuring について

    const { createNodeField } = actionsという書き方は、モジュールから、必要なメソッド(等)のみを抽出するES6の書き方。 この場合は、actionsオブジェクトからcreateNodeFieldを抽出している。 Actionsに下記の記載

    The object actions contains the functions and these can be individually extracted by using ES6 object destructuring.

    個別に展開 が正しい訳か。

    Tags