moyashidaisuke's diary

平日はエンジニア、土日はミュージシャン(自称)のダイスケです。プログラム関連とかギター関連とかなんでも。

個人ブログをはてなブログから Gatsby + Netify に移行した

モチベーション

  • 技術系、旅行系と記事の幅が広いので、もう少しカスタマイズしたい
  • wordpressは宗教的理由で使わない
  • せっかくだしナウい系の技術を触るようにしたい
  • はてなブログちょっと遅いよね
  • まあまあ時間かけてるので、そろそろ少しはマネタイズできるように独自ドメインにしたりしたい(ガチではやらないです。ついで程度)

採用技術

というわけで、チュートリアルで良さげだったのでGatsbyjsにします。 moyashidaisuke.hatenablog.com

vue.jsの方が馴染んでるんだけど、なんだかんだReactの方がメジャーなのである程度やっておきたいなーと。

サーバはNetlifyにします。Firebaseでも全然良いのですが、Netlifyの方が前から興味あったので、というだけの理由です。なんか合わなかったらFirebaseに移行します。

techblog.kayac.com

あと、Contentfulとの組み合わせも流行ってるようですが、記事をGit管理したいのと、今回はカスタマイズ性を求めてるので使わない方針で。

www.contentful.com

方針

  • 立ち上げ優先で
    • やり始めるときりないので、さっさと運用初めて、カスタマイズは後でやる
    • デザインも最小限で
  • はてなブログに書いた記事は移行する
  • ドメインはとる

はてなブログのエクスポート

blog.cheezenaan.net

motemen.hatenablog.com

macなのでbrew

 brew install Songmu/tap/blogsync

適当なディレクトリを作って設定ファイル書く

blogsync.yaml

moyashidaisuke.hatenablog.com:
  username: moyashidaisuke
  password: 秘密
default:
  local_root: 適当なディレクトリ

実行

blogsync pull moyashidaisuke.hatenablog.com

できました。

ファイルはマークダウン形式なのでこのまま使えそう。

f:id:moyashidaisuke:20190430182340p:plain

あっさり完了。

テンプレから初期セットアップ

環境セットアップ

チュートリアルで作ったdockerを流用。 さっくりいくと思いきや、後述の「雛形(template作成)」のところでエラーがでまくって試行錯誤した結果がこちら。

docker-compose.yml

version: '3'
services:
  node:
    build: node
    tty: true
    volumes:
    - ./node:/node:cached # cachedつけると早い
    ports:
    - "8000:8000"

Dockerfile

# ベースイメージを指定
FROM node:10-alpine

# node.js の環境変数を定義する
# 本番環境では production
ENV NODE_ENV=development

RUN apk add git curl python make g++ autoconf automake libtool nasm

# http://sharp.pixelplumbing.com/en/stable/install/
RUN apk add vips-dev fftw-dev build-base --update-cache \
    --repository https://alpine.global.ssl.fastly.net/alpine/edge/testing/ \
    --repository https://alpine.global.ssl.fastly.net/alpine/edge/main



RUN npm install -g gatsby-cli


# ディレクトリを移動する
#WORKDIR /blog


# ポート8000番を開放する
EXPOSE 8000

雛形(template作成)

これにしました。

www.gatsbyjs.org

github.com

gatsby new  blog https://github.com/greglobinski/gatsby-starter-hero-blog.git

yarn か npm か聞かれるので、npmにする(yarnだと動かなかった) ついでのnodeのバージョンも12だと動かなかった。

最後にgitのcommitまでしようとしてくれてエラーになるが、gitのコミットはhost側でやるので無視してOK

fatal: unable to auto-detect email address (got 'root@0ebab49be50e.(none)')



  Error: Command failed: git commit -m "Initial commit from gatsby: (https://github.com/greg  lobinski/gatsby-starter-hero-blog.git)"
  *** Please tell me who you are.
  Run
    git config --global user.email "you@example.com"
    git config --global user.name "Your Name"
  to set your account's default identity.
  Omit --global to set the identity only in this repository.
  fatal: unable to auto-detect email address (got 'root@0ebab49be50e.(none)')

起動

 gatsby develop -H 0.0.0.0

queries/secondSegmentation fault というエラーが出てしまうのだが何回かリトライすると動く。

ブラウザで localhost:8000 を叩いて画面が出ればOK。長かった、、、

f:id:moyashidaisuke:20190501200208p:plain

とりあえず公開

www.gatsbyjs.org

「Try this starter」 Netlifyのリンクがあるのでそちらから。

指示に従って進める

GitHub認証して、

f:id:moyashidaisuke:20190502124918p:plain

リポジトリ名いれてSave & デプロイ f:id:moyashidaisuke:20190502125041p:plain

デプロイ完了した事になってるが、実際にはまだ見られない。 ビルドコマンドやpathの設定がされてないので。 f:id:moyashidaisuke:20190502125019p:plain

というわけで設定してく

Gatsby用の設定の仕方がhelpに書いてあるので指示に従う

www.netlify.com

よく見たらあたしく作られたリポジトリにリンクされてしまっていたので(謎)、リポジトリの設定変更もした

f:id:moyashidaisuke:20190502130532p:plain

デプロイするとエラー発生

11:07:26 AM: error Plugin gatsby-plugin-algolia returned an error
11:07:26 AM: 
11:07:26 AM:   AlgoliaSearchError: Please provide an application ID. Usage: algoliasearch(app  licationID, apiKey, opts)

github.com

テンプレートのREADMEをよく読むと、ALGOLIAという外部サービスを使う前提になっているようなので、登録する。

Algoliaについてはこちら。

blog.leko.jp

READMEにブログへのリンクがある。

dev.greglobinski.com

なんかだいぶ画面が違ったけど、雰囲気で選ぶ(すいませんキャプチャ取り忘れ、、、)

必要なのはこの4つのパラメータ

ALGOLIA_APP_ID=... 
ALGOLIA_SEARCH_ONLY_API_KEY=...
ALGOLIA_ADMIN_API_KEY=...
ALGOLIA_INDEX_NAME=...

上の3つは「API Keys」メニューにある。「ALGOLIA_INDEX_NAME」は自分でIndex作成する時に指定したやつ。

.envをコミットしろ的な説明もあるんだけど、それは乱暴なのでNetlifyのenv機能を使って設定する。

f:id:moyashidaisuke:20190502132409p:plain

成功!

11:23:29 AM: Build ready to start
11:23:35 AM: build-image version: d5d16c91ca3e1e5a990086daa8a1d5bd8564d12a
11:23:35 AM: build-image tag: v3.2.2
11:23:35 AM: buildbot version: 93c10be3dc42bccef2b5600a7e10ec1d4a1c7051
11:23:36 AM: Fetching cached dependencies
11:23:36 AM: Failed to fetch cache, continuing with build
11:23:36 AM: Starting to prepare the repo for build
11:23:36 AM: No cached dependencies found. Cloning fresh repo
11:23:36 AM: git clone https://github.com/daisuke-fukuda/gatsbyjs-blog
11:23:37 AM: Preparing Git Reference refs/heads/master
11:23:38 AM: Starting build script
11:23:38 AM: Installing dependencies
11:23:40 AM: v10.15.3 is already installed.
11:23:41 AM: Now using node v10.15.3 (npm v6.4.1)
11:23:41 AM: Attempting ruby version 2.6.2, read from environment
11:23:42 AM: Using ruby version 2.6.2
11:23:43 AM: Using PHP version 5.6
11:23:43 AM: Started restoring cached node modules
11:23:43 AM: Finished restoring cached node modules
11:23:43 AM: Installing NPM modules using NPM version 6.4.1
11:24:36 AM: > deasync@0.1.14 install /opt/build/repo/node/blog/node_modules/deasync
11:24:36 AM: > node ./build.js
11:24:37 AM: `linux-x64-node-10` exists; testing
11:24:37 AM: Binary is fine; exiting
11:24:37 AM: > sharp@0.21.3 install /opt/build/repo/node/blog/node_modules/sharp
11:24:37 AM: > (node install/libvips && node install/dll-copy && prebuild-install) || (node-gyp rebuild && node install/dll-copy)
11:24:38 AM: info
11:24:38 AM: sharp Downloading https://github.com/lovell/sharp-libvips/releases/download/v8.7.0/libvips-8.7.0-linux-x64.tar.gz
11:24:41 AM: > gatsby-telemetry@1.0.9 postinstall /opt/build/repo/node/blog/node_modules/gatsby-telemetry
11:24:41 AM: > node src/postinstall.js
11:24:41 AM: > cwebp-bin@5.0.0 postinstall /opt/build/repo/node/blog/node_modules/cwebp-bin
11:24:41 AM: > node lib/install.js
11:24:41 AM:   ✔ cwebp pre-build test passed successfully
11:24:41 AM: > mozjpeg@6.0.1 postinstall /opt/build/repo/node/blog/node_modules/mozjpeg
11:24:41 AM: > node lib/install.js
11:24:42 AM:   ✔ mozjpeg pre-build test passed successfully
11:24:42 AM: > pngquant-bin@5.0.2 postinstall /opt/build/repo/node/blog/node_modules/pngquant-bin
11:24:42 AM: > node lib/install.js
11:24:43 AM:   ✔ pngquant pre-build test passed successfully
11:24:47 AM: npm
11:24:47 AM: WARN gatsby-starter-hero-blog@2.0.0 No repository field.
11:24:47 AM: npm
11:24:47 AM: WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.9 (node_modules/fsevents):
11:24:47 AM: npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.9: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
11:24:47 AM: added 2612 packages from 1405 contributors and audited 43643 packages in 63.028s
11:24:47 AM: found 2 vulnerabilities (1 low, 1 moderate)
11:24:47 AM:   run `npm audit fix` to fix them, or `npm audit` for details
11:24:47 AM: NPM modules installed
11:24:47 AM: Started restoring cached go cache
11:24:47 AM: Finished restoring cached go cache
11:24:47 AM: unset GOOS;
11:24:47 AM: unset GOARCH;
11:24:47 AM: export GOROOT='/opt/buildhome/.gimme/versions/go1.12.linux.amd64';
11:24:47 AM: export PATH="/opt/buildhome/.gimme/versions/go1.12.linux.amd64/bin:${PATH}";
11:24:47 AM: go version >&2;
11:24:47 AM: export GIMME_ENV='/opt/buildhome/.gimme/env/go1.12.linux.amd64.env';
11:24:47 AM: go version go1.12 linux/amd64
11:24:47 AM: Installing missing commands
11:24:47 AM: Verify run directory
11:24:47 AM: Executing user command: gatsby build
11:24:50 AM: success open and validate gatsby-configs — 0.029 s
11:24:52 AM: success load plugins — 1.305 s
11:24:52 AM: success onPreInit — 0.012 s
11:24:52 AM: success delete html and css files from previous builds — 0.010 s
11:24:52 AM: success initialize cache — 0.026 s
11:24:52 AM: success copy gatsby files — 0.025 s
11:24:52 AM: success onPreBootstrap — 0.008 s
11:24:52 AM: success source and transform nodes — 0.299 s
11:24:52 AM: success building schema — 0.394 s
11:24:52 AM: Using environment config: 'production'
11:24:53 AM: success createPages — 0.107 s
11:24:53 AM: success createPagesStatefully — 0.104 s
11:24:53 AM: success onPreExtractQueries — 0.004 s
11:24:53 AM: success update schema — 0.083 s
11:24:53 AM: success extract queries from components — 0.231 s
11:24:53 AM: success run static queries — 0.113 s — 1/1 8.96 queries/second
11:24:54 AM: warning code block or inline code language not specified in markdown. applying generic code block
11:25:02 AM: success run page queries — 8.551 s — 27/27 3.16 queries/second
11:25:02 AM: success write out page data — 0.004 s
11:25:02 AM: success write out redirect data — 0.001 s
11:25:46 AM: success Build manifest and related icons — 0.000 s
11:25:46 AM: success onPostBootstrap — 0.003 s
11:25:46 AM: info bootstrap finished - 58.174 s
11:26:26 AM: success Building production JavaScript and CSS bundles — 40.282 s
11:26:35 AM: success Building static HTML for pages — 8.901 s — 27/27 24.92 pages/second
11:26:46 AM: success index to Algolia — 10.743 s
11:26:46 AM: Generated public/sw.js, which will precache 10 files, totaling 443815 bytes.
11:26:46 AM: info Done building in 118.347 sec
11:26:46 AM: Build script success
11:26:46 AM: Starting cache prep script
11:26:46 AM: Caching artifacts
11:26:46 AM: Started saving node modules
11:26:46 AM: Finished saving node modules
11:26:46 AM: Started saving pip cache
11:26:46 AM: Finished saving pip cache
11:26:46 AM: Started saving emacs cask dependencies
11:26:46 AM: Finished saving emacs cask dependencies
11:26:46 AM: Started saving maven dependencies
11:26:46 AM: Finished saving maven dependencies
11:26:46 AM: Started saving boot dependencies
11:26:47 AM: Finished saving boot dependencies
11:26:47 AM: Started saving go dependencies
11:26:47 AM: Finished saving go dependencies
11:26:48 AM: Cache script success
11:26:48 AM: Starting to deploy site from 'node/blog/public'
11:26:48 AM: Creating deploy tree 
11:26:49 AM: 82 new files to upload
11:26:49 AM: 0 new functions to upload
11:26:53 AM: Starting post processing
11:26:57 AM: Post processing done
11:26:57 AM: Site is live
11:27:26 AM: Finished processing build request in 3m50.593483821s
11:27:26 AM: Shutting down logging, 0 messages pending

Netlifyが発行したドメインでアクセスすると動いてる!

f:id:moyashidaisuke:20190502132931p:plain

ドメイン設定する

ドメイン買う

まずはドメインを決めて買います。

お名前.com -> なぜか最後の申し込みでエラー(海外にいたから?

むーむー -> ユーザー登録でSMSが必要で登録できず(海外でデータ専用のSIMを使ってたので不可

さくら -> できた

というわけで、moyashidaisuke.com を買いました。

netlifyに設定する

www.ravness.com

Unless your DNS provider supports CNAME flattening, ANAME or ALIAS records for root domains, we strongly recommend setting the www subdomain as your primary domain. Our “To WWW or Not WWW” article has more details on why we recommend that configuration.

確かにwww付きをメインにすることを推奨してますね。

さくらの場合、whois情報の方から変更する事になるので注意が必要です。(1hくらいハマった、、、

きっかり24hくらいで、httpsの設定まで自動でされました。

諸々改修

dev.greglobinski.com

meta情報

/content/meta/config.js

module.exports = {
  siteTitle: "moyashidaisuke's diary", // <title>
  shortSiteTitle: "moyashidaisuke's diary", // <title> ending for posts and pages
  siteDescription: "平日はエンジニア、土日はミュージシャン(自称)のダイスケです。プログラム関連とかギター関連とかなんでも。\n",
  siteUrl: "https://www.moyashidaisuke.com",
  // pathPrefix: "",
  siteImage: "preview.jpg",
  siteLanguage: "ja",

  /* author */
  authorName: "moyashidaisuke",
  authorTwitterAccount: "moyashidaisuke",

  /* info */
  headerTitle: "moyashidaisuke's diary",
  headerSubTitle: "moyashidaisuke's diary",

  /* manifest.json */
  manifestName: "moyashidaisuke's diary",
  manifestShortName: "moyashidaisuke", // max 12 characters
  manifestStartUrl: "/index.html",
  manifestBackgroundColor: "white",
  manifestThemeColor: "#666",
  manifestDisplay: "standalone",

  // gravatar
  // Use your Gravatar image. If empty then will use src/images/jpg/avatar.jpg
  // Replace your email adress with md5-code.
  // Example https://www.gravatar.com/avatar/g.strainovic@gmail.com ->
  // gravatarImgMd5: "https://www.gravatar.com/avatar/1db853e4df386e8f699e4b35505dd8c6",
  gravatarImgMd5: "https://www.gravatar.com/avatar/3b0446884fc47b25b4bc2c8b06f97a24",

  // social
  authorSocialLinks: [
    { name: "github", url: "https://github.com/guitaristdaisuke" },
    { name: "twitter", url: "https://twitter.com/moyashidaisuke" },
    { name: "facebook", url: "http://facebook.com/moyashidaisuke" }
  ]
};

いらないページ削除

content/pages にある不要ページを削除(勝手にヘッダーからも削除されます)

 deleted:    node/blog/content/pages/2--starters/gatsby-starter-personal-blog.png
    deleted:    node/blog/content/pages/2--starters/gatsby-starter-simple-landing.png
    deleted:    node/blog/content/pages/2--starters/index.md
    deleted:    node/blog/content/pages/3--front-end-dev/index.md
    deleted:    node/blog/content/pages/4--privacy/index.md
    deleted:    node/blog/content/pages/5--terms/index.md
    deleted:    node/blog/content/posts/draft-post/index.md
    deleted:    node/blog/content/posts/draft-post/photo-1490474418585-ba9bad8fd0ea.jpg

デモのテキストを修正

英語で色々書いてあるので適当に削除

 node/blog/content/pages/1--about/index.md | 24 +++---------------------
 node/blog/content/parts/footnote.md       |  7 +------
 node/blog/src/components/Hero/Hero.js     |  3 ++-

過去記事いれる

フォルダ名、ファイル名の形式をあわせる必要があります。

2017-10-01--two-things-are-infinite/index.md

※日付の後がページのURLになるようです。

はてなのURL https://moyashidaisuke.hatenablog.com/entry/2019/04/30/172151

新URL https://www.moyashidaisuke.com/172151

こんな感じにしようと思います。

blogsyncで取得したファイルは、

年/月/日/{id}.md 年月日/{id}.md

が混在しています。多分、はてなブログの前にはてなダイアリーで書いてたものがあるからだと思います。

年月日/{id}.md (はてなダイアリー形式)

数も多くないいので手動で対応します。 ファイル名とフォルダ名はちまちまやります。

ヘッダーにcover(サムネ)が無いとエラーになるので、dummyを設定します。ついでにauthorも設定

cover: dummy.jpg
author: moyashidaisuke

Title -> titleに置換します

title: HerokuでPlay!を動かす その1

とりあえずこれで表示されます。カテゴリーとか動いてないけど後で。

f:id:moyashidaisuke:20190502170723p:plain

年/月/日/{id}.md(はてなブログ形式)

適当スクリプト作ってフォルダ名とファイル名をformat

<?php


$serch_dir = dirname(__FILE__) .'/moyashidaisuke.hatenablog.com/entry';

$files = new RecursiveIteratorIterator(
    new RecursiveDirectoryIterator($serch_dir,
        FilesystemIterator::CURRENT_AS_FILEINFO |
        FilesystemIterator::KEY_AS_PATHNAME |
        FilesystemIterator::SKIP_DOTS
    ),
    RecursiveIteratorIterator::SELF_FIRST
);

foreach($files as $path => $info) {
//    echo 'file path : '. $path              .PHP_EOL;
//    echo 'file size : '. $info->getSize()   .PHP_EOL;

    if ($info->isFile()) {
      $relativePath = str_replace($serch_dir. '/', '', $path);

      $dirs = explode('/', $relativePath);

      if (sizeof($dirs) != 4) {
        echo 'なんか形式が違う'. $path;
        continue;
      }

      if (pathinfo($path, PATHINFO_EXTENSION) != 'md') {
          echo 'なんか形式が違う'. $path;
          continue;
      }

      $newDir = $serch_dir.'/../'. $dirs[0].'-'.$dirs[1].'-'.$dirs[2].'--'.str_replace('.md', '', $dirs[3]);
      echo $newDir;


      mkdir($newDir, 0766, true);
      copy($path, $newDir.'/index.md');


      // dummy画像配置
      copy('./dummy.jpg', $newDir.'/dummy.jpg');

    }
    echo PHP_EOL;
}

あとは一緒。

なぜか TypeError: Cannot read property 'slug' of null というエラーが発生したが、gatsbyjsを再起動したらちゃんと読み込まれました。

あと、はてなブログで下書きのものもエクスポートされてるので、公開しちゃわないように注意( Draft: true となっています)。draft-post の下に移動しておきましょう。

色々表示は崩れますが、一応表示はされるようになりました。

※後で気がついたけど、{id} はidじゃなくて、時分秒なんですね、、、yyyymmddhhmiss形式にしておいた方がよかった、、、

Algoliaきる

過去記事をデプロイしようとしたところ、以下のエラーが発生。

 11:51:33 AM:   AlgoliaSearchError: Record at the position 152 objectID=/181521/0 is too big s  ize=11401 bytes. Contact us if you need an extended quota

www.algolia.com

そんな大きな記事じゃないんだけど、、、、そんな検索にニーズがあるとは思えないので機能を削ることに。

gatsby-config.jsの gatsby-plugin-algoliaのブロックを削って、pages/search.jsを削除すればOK

はてなブログからのforward設定

【SEO的にもOK】はてなブログでリダイレクト設定をする方法【JSリダイレクト】 | ナオユネット

↑はwordpressへの設定方法になっていますが、jsでごりっとやるのであれば今回も使えるはず、、、

というわけでjs書いていきます。

https://moyashidaisuke.hatenablog.com/entry/2019/04/29/225844

https://www.moyashidaisuke.com/225844

https://moyashidaisuke.hatenablog.com/entry/20120903/1346672014

https://www.moyashidaisuke.com/1346672014

になれば良いので、pathの最後のブロックだけ活かせばOK

<script>
   var newDomain = "https://www.moyashidaisuke.com"; // 新URL
  var replacedStr;
  var path = location.pathname;

  if(path.startsWith('\/entry')){ //記事ページの時

    // pathを/区切りで分解
    var ary = path.split('/');

    // 最後のブロックをidとして使う
    replacedStr = '/' + ary[ary.length - 1];

  } else {
      replacedStr = '';
  }

  var url = newDomain + replacedStr;

  // check
  console.log(url);


  var link = document.getElementsByTagName("link")[0];
      link.href = url;

  setTimeout("redirect()", 0); // 0秒後にジャンプ
  function redirect(){
      location.href = url;
  }
    
    
</script>

ブラウザで動作確認できればOK。 カテゴリはそもそも移行してないので無視。(pvもほとんど無いし)

まとめ

けっこう細かい調整が必要で思ったより時間かかりました、、、 というわけで、この記事を最後に次からは新しいブログの方だけ更新していく予定!

新しいブログはこちら。

www.moyashidaisuke.com

残タスク

  • カテゴリ
  • google analyticsとかseach console設定
  • はてな独自タグで書いてるやつの移行
    • 画像周り
    • リンク周り
    • Amazonへのリンク
  • アイコン設定
  • トップの画像変更
  • その他全体的にデザイン調整

参考

blog.cheezenaan.net

blog.mono0x.net

GatsbyJSのチュートリアルやってみた

きっかけ

www.jabba.cloud

ちょうどシンプルなWebサービスを作るお仕事があったので、ちょうど良さそうと思ったので試してみる事に。

何が良さそう?(やってみる前の印象)

GatsbyJS

他の静的サイトジェネレーター StaticGen | Top Open Source Static Site Generators

後発なので、採用されてる技術がモダンです。

私が使った事があるNuxt.jsも素晴らしいのですが、 GatsbyJSは静的サイトジェネレーターに特化していて、この用途に限定するのであれば機能も多く使いやすそうです。(Nuxt.jsはSSRとかもできる)

Reactベース

今だとほぼデファクトなので、色々便利。(雑) (個人的にはvue.jsの方が好きですが)

GraphQL

ローカルのリソースも基本GraphQLで取得する仕組みになっているそうです。 ということは、とりあえずデータをファイルで静的に持っておいて、将来的にはAWSのAppSync等のサービスとつないで拡張とかしやすそう。

aws-sampleでもサンプルコードを提供してくれていました。

github.com

AppSync自体がシンプルにDynamoDBからの取得もできるし、ちょっと複雑な事をする場合はLambdaを書けばいけるので、シンプルなWebサービスなら全然いけるイケてるやつ。

Netify

tech.qookie.jp

静的ファイルを置くだけならS3やfirebaseという選択肢もあるのだけど、静的ファイルに特化していて超使いやすい印象。

個人で使うならCDN付きで無料というのはすごい。

さらに、SPA系で困るSEO対策なのだけど、Prerendering機能もあるのでSEO対策もそこそこやってくれそう。

本気でやるとSSRしないといけなくて、ホスト環境からどうしようかという話になってなかなか大変なのだけど、こんな簡単にできるなら素晴らしい話。

www.netlify.com

qiita.com

まとめ

将来的な拡張をある程度は見据えつつ、Webサービスを最速で構築し、コスト(人もお金も)をかけずに運用するならとても良い組み合わせに思われます。

やってみた

公式チュートリアル(雑な要約付き)

www.gatsbyjs.org

0. Set Up Your Development Environment

完了後のソース

github.com

環境設定です。

もろもろ指定通りにインストールして、コマンド叩けばOKです。英語ですが、コマンドについての細かい説明もあって(cd の説明から)すごく丁寧です。

私はローカルにglobalで入れたくないのでdockerを使いました。

developコマンドで開発用のサーバを立ち上げる際は、

gatsby develop -H 0.0.0.0

とする必要があります。(チュートリアルにも記載があります)

これは、↓と同じ理由ですが、ENVからデフォルト設定を取ってくる実装になっていないので毎回指定する必要があります。

moyashidaisuke.hatenablog.com

実装はここ。PR出したら通るかなぁ、、

github.com

prettier

チュートリアルではVSCodeがおすすめされていますが、私はJetBrainのIDE(今回はPHPStorm。PHP使わないけど)を使っているので、環境に合わせてprettierをセットアップしました。

docker上に入れるとIDEとの連携が面倒なのでローカルに入れちゃっています。

prettier.io

npm install --global 

prettierへのpathをマニュアルと変えています。 f:id:moyashidaisuke:20190114144926p:plain

1. Get to know Gatsby building blocks

公開したサイト

http://unable-ocean.surge.sh/

完了後のソース

github.com

JSX、component(ここまでReactの説明)と、surgeを使った公開まで。

surgeについてはこちらが詳しかったです。

dotstud.io

2. Introduction to Styling in Gatsby

公開したサイト

http://untidy-balance.surge.sh/about-css-modules/

完了後のソース

github.com

cssの組み込みの説明。css-modulesを使ってscoped css実現。

3. Creating nested layout components

公開したサイト

http://obsequious-bean.surge.sh/

完了後のソース

github.com

layoutの説明。nuxt.jsのlayoutと同じでした。

4. Data in Gatsby

公開したサイト

http://six-detail.surge.sh/

完了後のソース

github.com

GraphQLとりあえず使ってみる編。

GraphQLの利用は必須じゃない(小規模ならcreatePages APIをつかえばGraphQL無しでできる。全然OKとのこと)

ここに限らず、npmパッケージのインストールはチュートリアルのコマンドだと遅いので、yarn使ったほうが良さそうです。(gatsby newではyarn使ってるので特にinstallは不要のはず)

yarn add gatsby-plugin-typography typography react-typography typography-theme-kirkham gatsby-plugin-emotion @emotion/core

5. Source plugins

公開したサイト

http://gusty-word.surge.sh/my-files/

完了後のソース github.com

4を発展させて、Source pluginsを使ってfilesystemからデータをGraphQLを使って取得し、画面に表示する。ブラウザでGraphQLを実行できるページ(___graphql)も。

GatsbyJSの真骨頂という感じ。

6. Transformer plugins

公開したサイト

http://assorted-coast.surge.sh/

完了後のソース

github.com

5をさらに発展させて、マークダウンで書いたファイルを読み込んで、GraphQLで扱う。Transformer plugins を使う事で、元ファイルがマークダウンでもGraphQLでいい感じにデータを扱えるようになる。

ブログの一覧ページを作るところまで。

7. Programmatically create pages from data

公開したサイト

http://ordinary-able.surge.sh/

完了後のソース

github.com

6をさらに発展させて、各記事ページを作成する。 graqhQLを使う事で何でもできるんだけど、書くことがけっこう多いな、という印象。

ページの作成はここまで。

まとめ

全体的にReactとGraphQLをベースに使う事で、モダンにできてるな〜という印象です。できるものも、ユーザー体験として高速になるし。 プラグインも必要そうなものはかなり揃ってそう。

一方で非エンジニアにはまだまだ敷居が高そうで、wordpressの代わりにはほど遠い感じでした。(私はエンジニアなんでいいけど)

参考

www.gatsbyjs.org mottox2.com

shibe97.com

平成も終わるので私についての話をしよう

はじめに

ここ1年くらいかな?仕事が変わったり(これはブログでけっこう公開してますね)、プライベートでも色々あったりしまして(こっちはあまりpublicにする事でもないかなと思っているので書いてませんね。気になる方は飲みにでも誘ってください)、何気にばたばたしております。

普段接点がそれほど多くない方でもけっこうブログ読んでいただいているようで、大変ありがたい事なのですが、逆にちょっと誤解されてる事もあるのかな?と思ったので、実際どうなのよ的な事を書ける範囲で書いてみます。

SNSやブログ等の全世界に公開されるものについては、ポジティブな情報しか書かないようにしようと思っていたのですが、なんかそれって表面的に取り繕った情報を発信してるだけで、かえって誤解の元なんじゃないの?と思うようになってきました。もちろん半永久的にネットの海に残るものなので、何でも書いていいよとまでは思わないですが、ポジティブじゃない情報を何も出さないのも良くないような、、、という温度感です。

対面であればもっと色々なお話もできたりするのでしょうが、全ての人と十分なコミュニケーションを取るには人生100年とは言っても短すぎるので、少しでも共有できたらな〜と思ってつらつら書いてみます。

よくある質問と答え

色々チャレンジしてて楽しそうっすね!

はい、チャレンジは確かにしているのですが、正直足掻いている感が強くて、心の底から楽しんでたり充実しているかと言うとそうでもなかったりします。

数年前まで

仕事も趣味の音楽も、それ以外にも眼の前にやりたい事(かつすごく大事なこと)がたくさんあって、本当に時間が足りなかったです。

よくあるこういう図だと(時間管理マトリックスというらしい)

http://www.franklinplanner.co.jp/system/img/imp_img1.jpgイントロダクション:1 重要領域に生きる|フランクリン・プランナー・ジャパン株式会社

重要かつ緊急、重要かつ緊急でない 事にたくさん時間と労力を割けていたと思います。

仕事でいうと、

  • バンドマンやめてサラリーマンになるために勉強しまくる
  • なんとか就職はできたのでそこで実力つけて評価されるように勉強しまくる
  • ユーザー向けサービスを作りたかったので転職して、求められるスキルセットが全然違うので必死に追いつくように勉強しまくる

という感じでした。25歳くらいで未経験で仕事を始めたので、本当に必死でした。

  • 早く一人前の仕事ができるようになりたい
  • フリーターの時にはお金と時間が無くて我慢していた色々な事をやりたい

という中期的に重要だと思える目標があって、それに向けて頑張っていました。

一方で最近は

ありがたい事に↑で考えていた2つの目標はほぼ叶っています。上を見たら本当にキリがないですが、ありがたい事にフリーランスとしてお仕事をしっかりといただけておりますし、お金と時間についてもかなりコントロールできるようになりました。

嫌いだった洗濯をしなくて良いくらいには。

moyashidaisuke.hatenablog.com

それで、次の中長期的な目標ってなんだろう〜と悩んでいるのが現状です。

https://jibun-compass.com/wp-content/uploads/2018/03/29249542_1186200631516680_3234511068566913024_o-1.png マズローの欲求5段階説をこの上なく丁寧に解説する。あなたの欲求はどのレベル? | 自分コンパス

マズローの欲求5段階説でいうと、こんな感じです。

- 仕事はじめた頃 最近
生理的欲求 だめ ok
安全の欲求 だめ ok
所属と愛の欲求 だめ 一時期満たされてたが今だめ(後述)
承認の欲求 だめ ok
自己実現の欲求 だめ だめ

海外で仕事してみたいな〜とか、自分でサービス作ってみたいな〜とか他にも色々思ったりはするのですが、以前のようなものすごい情熱は今の所感じられず、とはいえ考えるだけでもしょうがないので、できる事を色々やって試してみよう!とやっています。

めっちゃ悩んでるんで話聞いてください!

めっちゃ一人で充実してそうですね!

これも大体↑と同じですね。ぶっちゃけ一人でいるの飽きましたw

よく一人で旅行に行っていますが(今もタイのチェンマイにいます)、同じ環境で一人でいるのが耐えられないだけです。知らない所にいくのは好きなので、基本的には楽しいのですが一人旅の仕方も大体わかってきて(そう思った頃が危ないので注意します)、昔ほどの刺激は無いです。まあ楽しいんですけど。

twitterとかでだらだら実況してる時は大体こういう気分の時です。

仕事はフリーランスになり、音楽活動はかなり控えめになり、パートナーもおらずという状態は大人になって初めてなのですが、これは私には無理だという事が分かりました。一人でも粛々とモチベーションを保ってやり続けられるタイプの方もいるとは思いますが、私は違いました。(今までそういうタイプだと思ってたんですけどね。時が経って変わったのか、自分で知らなかっただけなのかはわかりません)

なので、ちょいちょい絡んでくれる友人は本当にありがたいと思っています。うまく表現できてないかもしれませんが、すごくうれしいです。

フリーランスとして働いてるのすごいね!

ありがとうございます。自分で色々選択できる状態であるのは、本当に恵まれていると思っています。

まあ努力はもちろん色々しましたが、エンジニアになろうと思ったのも戦略性があったわけではなく、仕事自体が自分にあっていたのも運の要素が強いです。

www.u-tokyo.ac.jp

最近は特にエンジニア界隈だとフリーランスという働き方が注目されていて、希望する方も多いようですが、本当にメリット・デメリットがあって、メリットだけが騒がれすぎていると感じています。別にそんなすごい事では無いです。

また、「所属と愛の欲求」が強いタイプである事が前述の通り判明したので、正直フリーランス向いてないな〜と最近は思っています(もちろんお仕事は一生懸命、ちゃんと成果だしてますよ!)。

こういった悩みを吐き出す場って、会社に所属してないとかなり意識的にしないとないんですよ!会社って年に1回か2回、人事考課とかで振り返ったり、相談する時間ありますよね。フリーランスって自分でしないと何も無いんですよー。

まとめ

どうでしょう?少しは私のイメージ変わりましたね?そうでもない?

みなさま、こんな私ですが引き続きよろしくおねがいします。

脳ドックと肺・心血管ドック受けてみた

また、先日、脳ドックのおかげで助かった友人(後述)がいましたので、これを機に

友人のお話を聞いて

medium.com

こちらのお話を聞いて申し込む事にしました。

エンジニアなので、脳に何かあったらエンジニアとして仕事を続けるのは難しくなります(脳に限った話ではないですが、代替手段が無いという意味で)。

ざっとググったところ、「メディカルチェックスタジオ」さん以外でもやってるところはけっこうあるようですが、今回は「メディカルチェックスタジオ」さんで行きます。

申し込み

medicalcheckstudio.jp

WEBで10分くらいで申し込めます。大変楽です。

診断自体は30分程度で終わるうえ、土日にもやっているのでかなり受けやすいと思います。私は申込日の翌々日の仕事前(9:15〜)行くことにしました。

オプションで「肺・心血管ドック」も受けられるという事で、こちらにもせっかくなので申し込みました。(ちょろい) medicalcheckstudio.jp

両方合わせて ¥25,000円(税別) - クーポンで割引

受けてみた

¥2,000でお腹の脂肪のスキャンもできるよ!との事だったので合わせて受けることに(ちょろい)

流れはこんな感じでした

  • お着替え所に案内される
  • 金属系のアクセサリー(ベルドとか)をはずす(服は来たまま)
  • 肺・心血管ドック(お腹もこのタイミングかな?
    • 台に寝る
    • 2回パシャッとやって終わり
    • 1,2分でおしまい
  • 脳ドック
    • 肺・心血管ドックとは別のマシン
    • 台に寝る
    • 頭が動かないようになんか装着される
      • 痛いやつじゃないです
    • 10分くらい撮影される
      • ピーとかガーとか音出ます(けっこう不快
      • 振動もあります
      • なんか装着されてて動けない事もあって、けっこう圧迫感があります。

これだけ。実質2,30分くらいかな?

結果

お腹まわりはその場でもらえます。 恥ずかしいので色々隠してます。強制的に現実と向き合わされる感じ半端ない。(お腹の肉的に)

f:id:moyashidaisuke:20190416111310j:plain

脳と肺・心血管は3日後にメールで案内があります。結果を聞くのに再度行く必要は無いです。

検査結果はこんな感じで見られます。画像を拡大したり、スライドでアニメーションで見られたり(自分の輪切りを、、)、なかなか面白いです。私は特に大きな何かは見つからず、でした。

medicalcheckstudio.jp

たまたま、中の方とお話できたのですが、元楽天だったらしく、ちゃんとIT化されてるのはさすがだな〜と思いました。

www.msn.com

まとめ

  • とにかく簡単
    • 申し込み、検査、結果受領までUXが大変良い
  • 受けてみた結果、なんとなく安心した
    • 見つかれば早めに見つかって良かったにつながる
    • 見つからなくても安心を手に入れられる

「東京都庭園美術館」の庭園でノマドしてきた(してる) #ノマド #東京都庭園美術館

ここです。

www.teien-art-museum.ne.jp

f:id:moyashidaisuke:20190420113815j:plain

庭園だけであれば、¥200で入れます。

www.teien-art-museum.ne.jp

今なら年間パスポートも売っていて、¥1,500です(買いました)。1枚で2人まで入れます。声かけてくれればこの年パスで一緒に入りましょうw

www.teien-art-museum.ne.jp

  • 外は気持ちが良い
    • エンジニアは引きこもりがちなので日光を浴びましょう
  • Wifiは一応飛んでいるが弱い
  • 電源は無い
  • 多くは無いが椅子と机もある
    • ブルーシートもってって芝生も良い
  • (有料なので?)空いてる
  • おしゃれなレストランもある
  • 自販機とかは無い

技術書オンリーイベント「技術書典6」に一般参加してきた

一般(サークルじゃない)方で初参加してきました。

techbookfest.org

技術書典とは?

techbookfest.org

技術書の同人誌即売会(頒布会)です。

技術書とは、

「ITや機械工作とその周辺領域について書いた本」を指します。ソフトウェア、ハードウェア、開発環境、コンピュータサイエンスからその他科学・工学全般などのジャンルを対象としています。

とのことです。私が仕事にしているWEB系のエンジニア向けだけではなく、ハードとかサイエンスとかもっと広いです。

技術書典ここがすごい

支払いアプリを自作している

AndroidiOSもあります。さすがエンジニア中心のイベント・・ 小銭があまりいりません。

技術書典

技術書典

  • Tatsu-zine Publishing Inc.
  • ビジネス
  • 無料

play.google.com

ダウンロード販売に対応している(ところが多い)

↑のアプリ経由でpdfをダウンロードできます。(サークルによっては電子書籍系のサービスを別途使っていたり、独自でやっていたり色々ですが、電子版ありきのサークルが多かったです。)

つまりKindleで読めます。物理本は場所を取ってしまうので苦手な人(私)にとっては大変有り難い。

事前にチェックリストをWEBで作れる

こんな感じです。

f:id:moyashidaisuke:20190414190609p:plain

サークルにチェックする(スターをつける)と、サークル配置図に色がつきます。ありがてえ、、、

さらにこのチェックされた数はサークルが把握できるようになっているそうです。つまり、何部刷るかの参考にできます。

チェックされた数がどれくらい参考になるかは前回のデータが参考になります。

blog.techbookfest.org

戦利品

技術云々ではなくて、エモい系の本買ってますね、、、

感想

つらつらと

  • 楽しかった
    • サークルを眺めたり、見本を読んでるだけでも楽しい
  • 混んでた
    • 世の中にはこんなにエンジニアがいるのか、、、
    • 動線がちょっときつかった
  • publicにできないもの(XXXをハックした(犯罪じゃない範囲で))とかはこういう会ならでは
  • けっこうお値段高め
    • と思ったけど、そもそも技術書って高いですしね

次は自分も何か書いてみたいな〜と思いました。

高知で初カツオ食べてノマドしてきた #ノマド #高知 #旅行

Jetstarのセールですごく安かったので一泊二日で強行(いつもの)してきました。

まとめ

  • 初カツオ美味しい
  • 高知はノマド環境きつめ
  • 高知の人は酒豪
  • 11月の戻りカツオが美味しいらしいので次は11月
  • カツオ美味しい

Jetstar

片道¥1,980 + 手数料諸々で往復合計¥6,000 でした、、、安すぎ

f:id:moyashidaisuke:20190413153637p:plain

今(2019/4/13)もやってますが、ここまで安くはないですね。

www.jetstar.com

適当に観光とか

これで行きます

空港での第1カツオ

100円のメンチカツ頼んだら150円くらいのささみカツをおまけでくれた。嬉しいけど謎w

駅前の三銃士その1 やなせたかしが高知出身なんですね。

駅前の三銃士その2

第2カツオ。最高にうまい。厚みが3chmくらいあって塩とレモンで食べる。最高。

タケノコとイタドリという山菜。高知ではけっこう取れるらしい。美味しい。

アオサの天ぷら。美味しい。

第3カツオ。美味しい。

高知を象徴するやべーゆるきゃら

手荷物検査場にいる微妙なクオリティの竜馬。

高知を代表する有名人ガチャガチャ。小野Dがいる

高知城

これはボスがいるダンジョンですね

これはボスが降臨しましたね

少し遠くから

夜景的な

GoPROは夜だとけっこうきついなぁ

ノマド

高知アイスカフェ よさこい咲都 (旧K’s caff)

tabelog.com

macaro-ni.jp

サークルKはファミマになったので、こちらもファミマに隣接するカフェになってました。

電源があるのは良いのだけど、WifiがファミマWifiしか無いです。ファミマWifiは20分×3回しか使えないのできつかったです。

文旦トマトジュースは美味しくてびっくりした。

COCOCHIコーヒー(旧エキカフェ)

tabelog.com

こちらは電源と、Wifiも遅いけどあったのでなんとかなるレベル。 コーヒーは普通。

ブックオフカフェ

tabelog.com

ノマドできる的なブログ記事を見つけたのですが、今は縮小されたのか外しかスペースしかありませんでした。この時期は寒いですし、電源も無さそう。

ノマドまとめ

今回は良い感じの場所を見つけられませんでした、、、スタバも中心地からはちょっと離れた所にあるし、、、宿泊先のホテルでやるのが安定な気がします、、、

所感とか

  • みんな土佐弁で話してるので坂本龍馬大河ドラマ気分になる
  • 献杯、返杯しないと怒られる
    • 「たっすい〜」と怒られる(冗談っぽくですよw
  • 高知の人は大きい買い物する時は車で半日かけて神戸とか大阪まで行く
  • jetstarで安く行ける事は地元の人はあまり知らない
    • JALANAで数万円かけて来たと思われるので、すごく感謝される
  • ゲストハウスに泊まったんだけど、濃い人しかいなかった。自分はなんて平凡なんだろう、と思ったw

献杯/返杯について www.kochi-bank.co.jp