あいつの日誌β

働きながら旅しています。

Gatsby v1.3.0 を試す(3)

前回のおさらい

Gatsby は Node.js 製の Static Site Generator です。JSON ファイルのようなデータ構造からも静的ファイルを生成する事ができます。 今回は WebAPI から fetch する方法を紹介します。

前々回、前回と違い外部API から resouce を取得して Gatsby の node を生成する plugin は v1.5.3 時点でまだ存在しません。その為自身でこれらの処理を記述する必要があります。

準備

プロジェクトを作成します。

gatsby new practice-gatsby-http && cd $_
yarn add node-fetch
touch gatsby-node.js

今回使用する WebAPI ですが、面倒なので http://jsonplaceholder.typicode.com/posts をそのまま使用します。

gatsby-node.js に sourceNodes 関数を追加します。sourceNodes に関しての詳しい説明は以下のページをご覧ください。

https://www.gatsbyjs.org/docs/node-apis/#sourceNodes

sourceNodes 関数

nodes 生成時に必要なデータをファイルから読み込む為に gatsby-node.js に以下の処理を追記します。

yarn add node-fetch

gatsby-node.js を修正します。

const crypto = require('crypto');
const _ = require(`lodash`);

exports.sourceNodes = async ({ boundActionCreators }) => {
  const { createNode } = boundActionCreators

  const posts = await fetch("http://jsonplaceholder.typicode.com/posts?_limit=20").then(res => res.json())

  // Process data into nodes.
  posts.forEach((post) => {
    createNode({
      post,
      id: post.id + "", 
      children: [], 
      parent: "posts",
      internal: {
        type: "posts",
        content: JSON.stringify(post),
        contentDigest: crypto
          .createHash(`md5`)
          .update(JSON.stringify(post))
          .digest(`hex`),
      }   
    })  
  })  
  return
}

動作確認

GraphiQL で allPosts と posts クエリーをそれぞれ発行する

query {
  allPosts {
    edges {
      node {
        id
        post {
          id
          title
          body
        }
      }
    }
  }
}
query {
  posts(id: {eq: "1"}) {
    post {
      id
      title
      body
    }
  }
}

まとめ

というわけで3回に渡って Gatsby の主幹となる nodes を生成する処理について紹介しました。実際に Page を生成するにはも少しステップが必要なのですがまた気が向いた時に tutorial でも作りたいと思います。

Gatsby v1.3.0 を試す(2)

前回のおさらい

React.js の component を使って Blog などを生成できる Gatsby という Node.js 製の Statice site generator を紹介しました。 Markdown だけでなく JSON ファイルのようなデータ構造からも静的ファイルを生成する事ができるので今回はそのやり方を紹介します。

ちなみに、v1.3 を試していたらすでに v1.5 になっていました。タイトルどうしよう。

準備

プロジェクトを作成する

gatsby new practice-gatsby-json && cd $_

Source plugin を追加する

nodes 生成時に必要なデータをファイルから読み込む為のプラグインを追加する。

yarn add gatsby-source-filesystem

gatsby-config.js を修正し、プラグインを設定します。

module.exports = {
   siteMetadata: {
     title: `Gatsby Default Starter`,
   },
-  plugins: [`gatsby-plugin-react-helmet`],
+  plugins: [
+    `gatsby-plugin-react-helmet`,
+     {
+      resolve: `gatsby-source-filesystem`,
+      options: {
+        path: `${__dirname}/src/pages`,
+        name: 'pages',
+      },
+    }
+  ],
 }

Transformer plugins を追加する

nodes 生成時に JSON 形式から変換させるプラグインを追加する

yarn add gatsby-transformer-json

gatsby-config.js を修正し、プラグインを設定します。

         path: `${__dirname}/src/pages`,
         name: 'pages',
       },
-    }
+    },
+    `gatsby-transformer-json`,
   ],
 }

json ファイルを用意

jsonplaceholder のデータをお借りします。以下のような json ファイルを src/pages/posts.json として保存します。

[
  {
    "id": "1",
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  },  
  {
    "id": "2",
    "title": "qui est esse",
    "body": "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla"
  }
]

動作確認

yarn develop

http://localhost:8000/___graphql を開いて以下のクエリを実行します。

一覧取得

{
  allPostsJson {
    edges {
      node {
        id
        title
        body
      }
    }
  }
}

f:id:okamuuu:20170729145544p:plain

詳細取得

query {
  postsJson(id: {eq: "1"}) {
    id
    title
    body
  }
}

f:id:okamuuu:20170729145556p:plain

まとめ

というわけで JSON ファイルから nodes を生成する方法を紹介しました。gatsby@1.0.0 以降から nodes を生成するのに markdown 以外の方法が増えたので gatsby の可能性に私はとても期待しています。

次回は http で外部API を fetch して、そこから nodes を生成する方法を紹介します。

Gatsby v1.3.0 を試す(1)

あらすじ

React.js と Vue.js のどちらが優れているかはどちらでも良いと思っています。なんですが React.js のエコシステム のほうが一歩先を歩んでいると思っています*1。私が React.js のエコシステムを推す理由に一つになっているツールがめでたくメジャーバージョンをリリースしたのでご紹介したいと思います。

Gatsby とは

Markdown を記述して Static な page を書き出すツールです。いわゆる Static Generator。今回のバージョンから Markdown 以外にも色々なところからデータを集積して Graphql で取り出すインターフェースが採用されました 。

f:id:okamuuu:20170726194358p:plain

私が Gatsby を好む理由ですが、React.js で書いた Compnent をそのまま利用できるところです。react-storybook 上に state less な compnents を集めている人はその財産をそのまま利用できます。

GraphQL とは

このあたりの記事を参考にすると良いのではないでしょうか。

GraphQL の概念とかその辺の記述を読んでいると時間かかると思いますが、最低限自分が必要な場面での使い方を覚える分にはそんなに時間かからないと思います。

GatsbyGraphiQL というツールを使って問い合わせできるので少しだけ紹介します。

github.com

Try GraphQL

やってみます。

npm install -g gatsby
gatsby new personal-blog && cd $_
npm run develop

次のような画面が出てきたら成功です。

 DONE  Compiled successfully in 182ms                                                                      15:27:47

 I  Your site is running at http://localhost:8000
 I  Your graphql debugger is running at http://localhost:8000/___graphql

http://localhost:8000/___graphql を開いてみましょう。これが graphiql の画面です。試しに以下のような Query を書いてみましょう。

query {
    allSitePage(limit:1000) {
      edges {
        node {
          id
        }
      }
    }
  }

そうすると以下のような画面になると思います。

f:id:okamuuu:20170726194216p:plain

Gatsby の Node について

詳しくは下記のドキュメントをご覧下さい。Gatsby は元となるデータをMarkdown であったり、JSON ファイルなどから集積しますが、その単位が以下の Node と呼ばれるものです。

https://www.gatsbyjs.org/docs/node-interface/

Graphql で問い合わせするのはこの node です。Gatsby をカスタマイズしたい場合は、node を作成する ことと Graphql で node を取得 する方法を覚えれば OK です。

Markdown で Node を追加して Grahpql で取得する

とりあえず一通り以下の Blog の通りに作業してみましょう。

www.gatsbyjs.org

手順通りに終わったら以下の Graphql を書いて見ましょう。以下が Markdown で記述された Node 一覧 です

query {
    allMarkdownRemark(filter: {}) {
      edges {
        node {
          id
        }
      }
    }
  }

以下のようなレスポンスが返ってくると思います。以下の例では Markdown のファイルを2個作成しています。

{
  "data": {
    "allMarkdownRemark": {
      "edges": [
        {
          "node": {
            "id": "/Users/okamuuu/personal-blog.bak/src/pages/08-12-2017-getting-next/index.md absPath of file >>> MarkdownRemark"
          }
        },
        {
          "node": {
            "id": "/Users/okamuuu/personal-blog.bak/src/pages/07-12-2017-getting-started/index.md absPath of file >>> MarkdownRemark"
          }
        }
      ]
    }
  }
}

次に Node 詳細 を問い合わせします。

query {
    markdownRemark(frontmatter: {path: {eq: "/hello-world"}}) {
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")
        path
        title
      }
    }
  }

以下の結果が表示されると思います。

{
  "data": {
    "markdownRemark": {
      "html": "<p>Oooooh-weeee, my first blog post!</p>",
      "frontmatter": {
        "date": "July 12, 2017",
        "path": "/hello-world",
        "title": "My First Gatsby Post"
      }
    }
  }
}

というわけでなんとなく Gatsby が集積した情報を問い合わせる方法が分かるんじゃないかと思います。

あと Front Matter について

下記に詳しい説明があるのでこの単語に聞き覚えがない方は一度ご一読下さい。

jekyllrb.com

まとめ

GatsbyMarkdown を使って Static Site を作る方法を学びました。 次回は JSON file から Static な Site を生成する方法を紹介します。

*1:React.js と Vue.js との優劣は議論する気はないのですがこれらのエコシスムの一長一短に関しての議論は歓迎します

夏らしさを求めておじさん2人が南伊豆へ旅した記録 2017

あらすじ

夏らしい事をしたいが、7月8月の週末は今回(7月22日の時点)を逃すと今年は最大でも6回しかない。チャンスは少ない。ならば俺たちは今すぐ行かねばならない。

どうしてそうなった?

あんまり覚えてないんですが確かこんな感じの話をしたんだと思います。

  • 夏らしい事をしたいよね
  • 海だよね!
  • シュノーケリングしたいんだよ
  • ところで南伊豆のヒリゾ浜はいい感じなんじゃないか?
  • 行ってみるか!
  • ついでにヒリゾ浜へ向かう途中でいい感じの砂浜を見つけるか!

という訳で南伊豆の海岸(東側と南側)を探索しました。

タイムテーブル

時間はあんまり正確じゃないですがこんな感じだったと思います。

初日

時間 内容
7月22日(土) 12:30 行くぞと決まる
7月22日(土) 13:00 品川へJR山手線で移動開始
7月22日(土) 13:30 熱海へ伊豆特急で移動開始
7月22日(土) 15:00 弓ヶ浜(下田)へレンタカーで移動開始
7月22日(土) 19:00 弓ヶ浜のもき丸で晩御飯
7月22日(土) 22:00 就寝

二日目

時間 内容
7月23日(日) 8:00 起床
7月23日(日) 8:30 弓ヶ浜の青木さざえ店で朝ごはん
7月23日(日) 10:00 チェックアウト
7月23日(日) 10:30 逢ヶ浜でシュノーケリングを楽しむ(素潜り)
7月23日(日) 11:30 ヒリゾ浜へレンタカーで移動開始
7月23日(日) 13:30 ヒリゾ浜シュノーケリングを楽しむ(素潜り)
7月23日(日) 14:30 熱海に向かってレンタカーで移動開始(下田街道を北上)
7月23日(日) 18:00 熱海到着レンタカー返却
7月23日(日) 18:30 解散
7月23日(日) 19:00 熱海 -> 品川へ新幹線で移動開始
7月23日(日) 19:50 品川へ到着

都内 -> 品川

特急踊り子号(伊豆急下田行) で。JR山手線内で移動中にスマホで席を確保します。えきねっとを使いましょう。品川駅で特急券を受け取ります。

品川駅で乗車券を受け取りつつレンタカーを手配します。最初、レンタカーは熱海のレンタリースのHPを見るも全て貸し出し中になっていました。電話したら何故か借りられたので今回はギリギリセーフ。 車借りられないと今回の旅は何もできないんで結構つらいのでちょっと危なかった。どの駅に降りるかは車を借りてから決めるようにすると良いでしょう。

品川 -> 熱海

さて、無事に新幹線に乗りました。さて現時点で我々のステータスは下記の通り。

  • 今回の旅は1泊2日でヒリゾ浜は素敵なんだろうかという調査をする。
  • 熱海で降りて、レンタカーを借りて下田へ移動する

現時点、ほぼ無策です。そんなわけで新幹線の移動時間を使ってスマホを使って情報収集を行います。この時間で計画、実行できた事

  • 南伊豆町にある弓ヶ浜というビーチもあるのでここを初日の目的地に定める
  • 宿泊所施設にチェックインして晩御飯を食べる
  • 翌日ヒリゾ浜へ向かう

熱海 -> 下田

という事でレンタカーを借りて移動開始、車内で楽天トラベルを使って宿泊所施設を予約し移動開始。大体90km ぐらいでしょうか。思った以上に伊豆半島は大きかった。次回ここに遊びに来る場合は下田まで列車で移動した方が良いという学びを得ました。

さていい感じの砂浜ですが、何をもっていい感じなのか決めないと評価できないので、とりあえずこの記事においては「沖縄の砂浜のように白い砂」だといい感じだと思ってください。

熱海サンビーチや伊東オレンジビーチも悪くはなかったのですが白い砂浜は伊豆先端である南伊豆まで行かねば発見できませんでした。

西側に関しては今回未調査です。

弓ヶ浜

f:id:okamuuu:20170725094558j:plain

というわけで弓ヶ浜に到着しました。大体19時ぐらいだったかな?晩御飯を食べたいので宿泊所の人にどこがいいのか聞いたところ「バーベキューガーデン海の家 もき丸」が良さそうでした。「青木さざえ店」も良さげでしたが残念ながら夕方で閉店しているのでどちらにしろ「バーベキューガーデン海の家 もき丸」しか選択肢は無かったんですが。

バーベキューガーデン海の家 もき丸

食べた物と飲んだものは以下の通り。写真はシッタカとトコブシです。

f:id:okamuuu:20170725094621j:plain

  • シッタカ
  • トコブシ
  • ピザ
  • イカの船上干し
  • ビール2杯
  • 白ワインハーフ

この店は店主が漁師でもあるらしいので海産物はとても美味しかったです。なぜかピザも美味しいっていう。夕暮れ時のビーチを眺めながら飲むビールは最高すよねえ。

ただ蚊とアリが少し多かったので虫除けが欲しかったですね。あとウェットティッシュ。淑女と一緒に行かれる予定がある方は必ずご持参ください。

就寝

おやすみなさい

DAY2

f:id:okamuuu:20170725094726j:plain

というわけで翌朝8:00ぐらいから活動開始。昨日行けなかった青木さざえ店で朝ごはん。

弓ヶ浜の駐車場事情

今回は宿泊所の駐車場を利用したので我々は特に料金は発生していないのですが、弓ヶ浜の駐車場事情について報告します。

まず1回1500円必要です。かつ、駐車場スペースが限られています。砂浜近くの駐車場は8時から9時の時点で満車になっていました。

路地を少しはいるとおじいちゃんとおばあちゃんがいて一回1000円の駐車場を案内していました。このお二人は朝ごはんを食べに行くときはいらっしゃいましたが朝ごはんから戻るといなくなっていました。そして1000円の駐車場が満車になっていました。

どうやら一回1000円の駐車場のほうも8時から9時には満車になるようです。 弓が浜へ遊びに行く予定がある皆さまは駐車場がどのあたりにあるのか事前にチェックしたほうが良さそうです。

弓ヶ浜ではなく逢ヶ浜

今回我々はシュノーケリングするスポットを探すほうが優先度が高かったので砂浜ではなく岩場へ行きました。

結構綺麗で海藻もたくさん生えていたので穴場スポットを見つけたのかもしれません。

ちなみに他にもシュノーケリングしている人がいましたがほとんどの人がラッシュガードをつけていました。カインズホームスーパーで買った980円のゴーグルと海パンだけで来ていたのは我々だけでした。この日は曇りだったのものすごく寒かったです。

ヒリゾ浜の駐車場事情

さてヒリゾ浜へ移動したのですがそもそも橋渡しポイントへの駐車場が満杯です。11:30 ごろに到着しのたですが、スタッフから「12:30ぐらいになれば午前中に来たお客様帰るので入れ替わりで駐車場が空くんじゃないかなあ」という説明を受けたのでそのあたりで昼ごはんを食べる事にしました。

つかさ庵

北へ 6km ほど移動して蕎麦屋さんを発見。暖かい鴨南蛮を食べました。まあまあ美味しかったです。同伴したおじさんは蕎麦好きでどうして冷たい蕎麦じゃないんだ!?という顔をしましたが逢ヶ浜で体温を結構失った私にとってはなかなかのご馳走でした。

再びヒリゾ浜

f:id:okamuuu:20170725094756j:plain

無事車を止めて渡し船を利用します。渡し船は1日券1500円です。ヒリゾ浜(岩場)へは船で移動する必要があり、1日に何度も往復しています。実質は1往復しかしない人がほとんどだと思います。

そして渡し船に。ダイビングスーツに身をまとった本格的な人たちがいる中、980円のゴーグルと海パンでやってきたおじさん2人が乗り込みます。

そして案の定海水が冷たい。しかし入らないと何しに来たのか分からない。というわけで頑張って水中へ。逢ヶ浜とは比べ物にならないほどの魚に遭遇。快晴だったらすごく幻想的な風景なんだろうなと思いました。

私はこの日、私は生まれて初めて Go Pro を買いたいと思いました。そして海を堪能して再び渡し船で戻ります。で戻って気づいたのですがウェットスーツとかレンタルしていました...

浄蓮の滝

f:id:okamuuu:20170725094819j:plain

さて無事に任務完了したので熱海へ向かって出発します。途中で河津七滝ループ橋を体験。昔の人は天城越えするのどんだけ大変だったんだろうと思いました。

で下田街道を通るのでしたら道の駅、浄蓮の滝はおすすめです。鮎の塩焼き美味しそうでしたがそこまでお腹空いてなかったので見送りしました。

f:id:okamuuu:20170725094921j:plain

ちなみにわさびのアイスクリームはちょっと微妙かな...ここはわさび作っててわさび田がありました。水綺麗。

そういえば伊豆ではテングサがたくさん取れるらしく、テングサでつくられたところてんは名物のようです。ところてんはおいしかったので機会があればぜひ食べてみてください。

ハムハウス Grimm

そして帰宅途中になんだか美味しそうな自家製ソーセージを作っているお店を発見。もう1人のおじさんが「最近ソーセージにはまっててこれを見逃す事ができない」とおっしゃったので立ち寄りました。保冷する必要があるので私は購入しませんでしたので美味しかったか不明ですが後日ヒアリングして追記しておきます。

熱海着

無事熱海に着いたのですが一方通行の道が多くて熱海をぐるぐる。ガソリンスタンドまでなかなかたどり着けないっていう。

でガソリンを満タンにしたのですが今回の旅は 300km 近く走ったのですが 12.04L しか消費していませんでした。

車種はなんだっけな...

私は車を所有していないのでどれぐらいすごいのか分かってませんがなんかすごいらしいです。

そして何故か人多すぎの熱海。知らない間に熱海が今盛り上がっているのか!?と思ったら熱海海上花火大会でした。

花火を見ながら酒を飲むなかなかの好機でしたがこれ以上体力を消耗すると明日の仕事に影響するだろうという事で見送りました。というわけで解散。

品川着

というわけで品川に到着しました。ちなみに熱海から品川駅までの新幹線のチケットを購入すると 熱海->東京山手線内 みたいな料金になるので品川駅からJR山手線の駅でしたら切符を買わなくても大丈夫です。

旅慣れてる人は知っているんでしょうけど東京とか、大阪とかそういうルールがあるのできになる方はぜひ調べて見てください。

まとめ

というわけで今回の旅で学んだ事

  • 日頃からアクティブに活動し、情報を収集している人々との交流は大事。
  • えきねっとユーザーにはあらかじめなっておきましょう。
  • 運転手を仲間に加えておきましょう。
  • レンタカーは借りられるのか、列車の出発時間はいつなのか日頃から検索する力を養っておきましょう。
  • 伊豆半島は思ったより大きかった。熱海から下田まで車での移動は苦行なので最初から下田まで列車で移動したほうがよいでしょう。
  • 海に行くなら日差しを避ける用のテントが必要
  • 海の家でご飯食べるなら虫除けとウェットティッシュが必要
  • シュノーケリングするならゴーグル、シュノーケル、ラッシュガード、フィンもしくはアクアシューズが必要。浮き輪もあれば尚可。
  • シュノーケリングするなら GoPro を購入しよう
  • 海に行って着替えをするときは大きめのタオルがないと不便

Failed: Cannot create property '__creationTrace__' on string '__zone_symbol__optimizedZoneEventTask'

どうした?

Angular なアプリを開発していたのですが CirlceCI 上でいきなりテストが通らなくなった

あと TypeError: Cannot create property '__creationTrace__' on string '__zone_symbol__optimizedZoneEventTask' とか言われます。

どうする?

調査した過程で、下記の issue にたどり着いた

github.com

とりあえず zone.js を v0.8.13 から v0.8.12 にダウングレードしました。おしまい。

Can't bind to 'ngModel' since it isn't a known property of 'input'. ("">

もう何度も同じメッセージを目撃し、時間を無駄にしているのでメモ

src/app/app.module.ts に FormsModule を追加する

 import { BrowserModule } from '@angular/platform-browser';
 import { NgModule } from '@angular/core';
+import { FormsModule } from '@angular/forms';
 
 import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
@@ -10,7 +11,8 @@ import { AppComponent } from './app.component';
   ],
   imports: [
     BrowserModule,
-    AppRoutingModule
+    AppRoutingModule,
+    FormsModule
   ],
   providers: [],
   bootstrap: [AppComponent]

qs v6.5.0 以降からちょっと便利になったのでメモ

addQueryPrefix と ignoreQueryPrefix が使えるようになりました。

assert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d');
var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true });
assert.deepEqual(prefixed, { a: 'b', c: 'd' });