Aokashi Room

なんでも書き続けるAokashiの部屋

DELL P2720DC を購入したのでレビュー

長らくモニターはフルHDのモニター2台のデュアルディスプレイでした。すでに片方は2012年に導入したモニターを使用していて寿命が近い*1ことと、フリッカーフリーといった目に優しい機能とかもなく頭が痛いことから、27インチの大型のモニターを導入しました。

今回購入した DELL の P2720DC はインターネットで検索する限りレビュー記事がほとんど存在しないため、この記事でレビューしてみようと思います。しかし、肝心の機能である USB Type-C 接続やデイジーチェーン接続については、対応機材を持っていないため省略しています。ごめんなさい。

*1:どこかでドット抜けがある、電源が入っていると僅かに動作音が聞こえる、・・・

続きを読む

はてなブログのデザインテーマ「Vertical BlogTheme」をテーマストアに投稿しました

f:id:aokashi:20200114120420p:plain

はてなブログのデザインテーマを投稿しました。

テーマについて

blog.hatena.ne.jp

今回投稿したテーマは「Vertical BlogTheme」です。明るい色と暗い色の組み合わせを目指しました。左側のコンテンツは明るい色で、各記事の項目には白い背景色を与えています。一方の右側のサイドバーは暗い色で、デザインのカスタマイズで背景を変更すると反映されます。サイドバーの暗い色が縦に伸びる意味で「Vertical」と名付けました。

WordPress の公式テーマ Twenty Fifteen をベースに、昔制作した WordPress のテーマの要素と、はてなブログの環境に合う要素を加えながらデザインしました。

ja.wordpress.org

f:id:aokashi:20160505115112p:plain
参考にしていた WordPress テーマの画像 (以前のブログ記事から持ってきました)

Twenty Fifteen は左側にサイドバーが配置されていますが、はてなブログでは右側にサイドバーを配置することがほとんどのため、右側に配置を変更しました。また、ヘッダーやフッターも、左側のコンテンツに配置しています。

スマートフォンでもタブレットでも同じデザインで表示できるレスポンシブデザイン対応のテーマです。

サンプルは下記のブログからご覧になれます。

vertical-blogtheme.hatenablog.com

既存のテーマであれば、「Gravity」と類似しているかもしれません。こちらは3カラムになります。

blog.hatena.ne.jp

開発の経緯

前からブログのデザインを変更して、ブログ更新のモチベーションを上げれば良いなと思っていました。

そこで、自分でテーマを作ろうと思ったのですが、結構手間が掛かりそうだと思い、作成せずに既存のテーマにカスタマイズを加えれば良さそうと判断しました。

しかしながら、後で調べてみると、はてなブログのデザインテーマ作成はCSSファイルのみということが分かり、これなら短時間で作成できると思って開発に至りました。

help.hatenablog.com

開発で時間がかかった箇所

短時間で作成できる と言いましたが、はてなブログのデザインテーマはCSSのみですので、レイアウトの配置に凝ってみようとすると、逆に時間がかかってしまいます。

背景色の割当

  • はてなブログのデザイン設定で背景画像を変更すると、右側のサイドバーにのみ反映されるようにしたかったため、サイドバー部分を透明にする必要がありました。
  • しかしながら、左側コンテンツ外側の背景も簡単に変更できるようにしたい関係で、その外側の背景を充てるセレクタの数も最小限にする必要もありました。

両者とも満たそうと実装しましたが、この場合だとサイドバー部分の位置を絶対座標にする必要がありました。

#container {
    background-color: #c0c0c0; /* 左側の背景色の割当は簡単なのだが... */
    position: relative;
}

#box2 {
    position: absolute;
    top: 0;
    left: 800px;
}

しかし、この場合だと、左側コンテンツの高さが、右側サイドバーの高さよりも低いと、右側サイドバーの背景が途切れるなど、レイアウト崩れが発生してしまいます *1

f:id:aokashi:20200114004144p:plain
サイドバーの方が高いとこんな感じになってしまう。

レイアウト崩れを起こさないようにすることも出来ないことは無いですが、結構大変な作業になることから、ブログタイトル、メイン、フッターそれぞれの要素に左側コンテンツの背景色を割り当てるようにしました。

そのため、左側コンテンツの背景色を変更しようとすると、下記のようになります。ちょっと面倒ですね。

#blog-title,
.header-image-enable #blog-title,
#wrapper,
#footer {
    background-color: (お好きな色);
}

WordPress だと、テーマのカスタマイズ機能があるおかげで、テーマを使用する側からは、簡単に色を変えることができます。

まあ、それ以前にはてなブログでは HTML の編集が出来ないので、出来るだけで解決する問題かもしれません。

左側コンテンツと右側サイドバーの幅のバランス

ここから先は、数学的な内容が含まれています。このために久しぶりに方程式を使いました。

このテーマはレスポンシブデザイン対応です。ということは、画面の横幅を変えると自動的にコンテンツの幅も変わります。

どのようにコンテンツの幅が変わるかを下図に用意しました。なお、 768px よりも狭い場合は1カラムレイアウトとみなし、コンテンツとサイドバーが同じ列に並びます。

f:id:aokashi:20200114114847p:plain
本テーマの横幅によるコンテンツの幅の決まり方

ここで悩んだのが、左側コンテンツ 外側 の幅の決め方でした。

まず最初に考えたのは、50vw + (左側コンテンツ内側の幅) / (何かの率) という計算式で、左側コンテンツ外側の横幅を決める方法です。50vw にした理由は、ブログのコンテンツが中央に寄って見やすくなると判断したためです。率の値は最初は適当に 4 としていましたが、後に 3.238 辺りに変更していました。

  • 例えばPC環境の場合、左側コンテンツ内側の幅は 868px です。実際に左側コンテンツ外側の幅は calc(50vw + 868px / 4) になります。

この方法で進めた結果、幅を変えるとヘッダーとコンテンツの幅が合わない事態が発生しました。

f:id:aokashi:20200113225323p:plain
コンテンツ内側の幅が変わる直後の幅だと、こんな感じで幅が揃わなくなる

スクロールバーが原因で画面の横幅が狭くなってしまい、コンテンツ内側の幅が確保出来ないから・・・というのもありましたが、デバイスごとに率の値が同じだと、違うデバイスで正しく幅が揃わないようです。

とりあえず 50vw にこだわるのをやめて、デバイス毎に幅を vw 単位で割り当てる方法を用意しました。左側コンテンツ外側の幅を決めるには、(左側コンテンツ内側の幅 / 指定したメディアクエリーの最小幅) * 100 で済みます。

  • 例えばPC環境の場合、メディアクエリーの最小値は 1200px です。先程の左側コンテンツ内側の幅である 868px と併せて使用すると、左側コンテンツ外側の幅は 72.3vw になります。

それをデバイス単位で設定したところ、幅が揃わない事態は直りましたが・・・。

f:id:aokashi:20200113230142p:plain
vw 単位のみで指定して 1920 × 1080 で閲覧した場合。右側サイドバーが狭くて違和感がある。

上図のように、幅を広げると内容がかなり右寄りになり、このテーマのコンセプトである「デザイン設定で設定した背景が大きく見えるようになる」と合いません。

そういったことがあって、一度 50vw から値を足す方法に戻って再び最適な方法を模索しました。デバイス毎に率を変えれば良さそうなので、下記関数を用意して計算してみました。

/**
 * 左側の横幅を取得します。
 *     このテーマは右側のサイドバーをなるべく広く取るために、画面の半分の幅をベースに、左側の横幅を計算しています。
 *     左側の横幅を取得するまでには、左側の内容の横幅を割るための率(ratio)が必要です。
 *     ratio はコンテンツとサイドバーの内側の幅で値が異なるため、ここで計算することになります。
 */
@function make-content-outer-width($viewport-width, $content-width) {
    $half-viewport-diff: $content-width - ($viewport-width / 2);
    $ratio: $content-width / $half-viewport-diff;
    @return calc(50vw + #{$content-width / $ratio});
}

// タブレット、PC(狭い)、PC(広い) それぞれに対応した左側内側の幅を設定 (実際は関数を使用して計算しています)
$content-width-sm: 520px;
$content-width-md: 660px;
$content-width-lg: 868px;
// それぞれの左側外側の幅を設定
$content-width-outer-sm: make-content-outer-width(768px, $content-width-sm);
$content-width-outer-md: make-content-outer-width(992px, $content-width-md);
$content-width-outer-lg: make-content-outer-width(1200px, $content-width-lg);
// 設定した変数はレイアウトに使用される

実際に動かしてみると、レイアウトが崩れず、ちゃんと中央に寄るようになりました。

ソースコード

GitHub に公開しています。変更履歴も、下記の GitHub の Releases から確認できます。

github.com

*1:実際 CSS でレイアウトする際に position: absolute を指定すると、あれこれ副作用が発生してしまうため、ちゃんとした形で実装するには結構難しい作業だったりします。

依頼生活3章 制作中!

f:id:aokashi:20200102220036p:plain
3章の中で出てくる舞台「サウシー町」の駅

おまたせしました。ながーい間公開できていないまま放置していた依頼生活の3章ですが、現在制作中です。

依頼生活とは?

2010年2月に1章が公開された長編のWWA作品です。1章は一番最初に公開されたWWA作品となります。3章構成になっていて、自分のWWA作品の中では唯一の複数章作品です。

物語

このゲームの舞台となっている惑星「森星 *1」では、地球温暖化が原因による災害が発生しています。今作の舞台であるハヅツ国も例外ではなく、近年台風の発生に頭を悩ますばかり。

この後絶対おかしい現象が起こるはずだと思った主人公は、翌日見事に的中。普段おとなしくしていたモンスターたちが急遽暴走してきました。本来なら出てこないスライムも出てきてしまい、住民は困惑しています。

普段だったら通っていた学校も、急遽国からの指導により、「冒険者学校」に変更。暴走を止めるために、国中くまなく散策することになります・・・。

ちなみに、この物語の文章はこのブログ記事の執筆時に刷新しました。

章について

  • 1章 ... 冒険者学校で状況を聞き、ハヅツ国北部を探索します。
  • 2章 ... セルドシティに到着後、ハヅツ国南部を渡ります。
  • 3章 ... ハヅツ国南部を探索し、謎の原因を追い求めます。

3章の制作状況について

3章はサントグ町に到着した主人公とその仲間が、まだ残っているとされている鍵を見つけ出すために冒険を進めます。

マップはすでに完成していて、後はメッセージやストーリーの追加、モンスターのバランス調整、最後のシーンの制作が残っています。なお、グラフィックは「謎めいた機械を追い求めて」で使用していたグラフィックを使用しています。

aokashi.hatenablog.jp

章毎にグラフィックが違うのは、WWA作品の中では数少ないかもしれません。プレイしてみると、進むたびにグラフィックが次第に進化していく・・・という小さいお楽しみ要素が待っています。

2章以前の手直しについて

ゲームのストーリーの設定を明確にしたり、優しすぎたゲームバランスを調整したりするため、2章以前のマップデータにも修正を加えます。

なお、だいぶ前に1章をリメイクしたことがありますが、リメイクしたマップは使用せず、すでにあるマップを修正する形で済ませます。

*1:住んでいる人からは森惑星と言っているのだが

2020年あけました

あけましておめでとうございます。 2020年もよろしくお願いします。

さて、気がついたら最初のホームページ「Coden City」設立からもうすぐ10年! このために Aokashi Home を GatsbyJS で作り直しました。

aokashi.hatenablog.jp

これから考えていること

WWA Wing の整理

現在、 WWA Wing のバージョンは 3.2.11。

github.com

2019年では、スタイルシートの SASS (SCSS) 化を担当しました。途中で $color マクロが動作しないバグが発生しましたが、後に修正されています。

現状の WWA Wing は packages/engine/src/ をあれこれ見ればわかるのですが、 ほとんどの処理が wwa_main.ts に集約されています。 ですので、なるべく別のファイルに移りしたりして、ソースコードを見やすいようにリファクタリングを進めています。

新しい WWA 作成ツールの模索

WWA マップ作成ツールに代わる新しい WWA の作成ツールを模索しています。

完成した場合は、そのタイミングで、 WWA のマップデータの仕様を公開したいですね。スーパー正男では、作成ツールが結構出ているので、 WWA も作成ツールを自由に選ぶ世の中になりたいです。 ただ、これは暗証番号がバレるリスクが高いため、慎重に進めようと思います。

その他

  • 就職活動を進めます。
  • 研究活動のテーマが未だにはっきり決まらず、迷走している状態なので、早いうちに決めておきたいです。

謎の機械を見つけるチャンス!「謎めいた機械を追い求めて」 WWA COLLECTION 2 へ収録!

WWA COLLECTION 2 が配信されました。前回と同じく、自分の作品が WWA COLLECTION 2 に収録されます。

aokashi.hatenablog.jp

収録作品「謎めいた機械を追い求めて」

f:id:aokashi:20191210135301p:plainf:id:aokashi:20191210134435p:plainf:id:aokashi:20191210134602p:plainf:id:aokashi:20191210135202p:plainf:id:aokashi:20191210135113p:plainf:id:aokashi:20191210135017p:plain

誰かが街に残した機械を撤去するために行動する主人公の物語です。Aokashi Home で公開している最後の作品「シティーアイランド」から5年ぶりの新作となります。

これまで制作したWWAのいいところを合わせた集大成として、演出やボリュームはできるだけ盛りました。

また、WWAを初めて知る方にも、WWAの文化を知ってもらうためにギミックも入れています。難易度は易しく設定しています。

  • 舞台は三角州となっている「すな地域」です。北はカンセツ連峰、南はヨコテ湾に面していて、昔から物流の中心地として栄えていました。
  • 時代は経済成長の真っ只中。住宅不足が問題となり、ニュータウンの建設を計画していたのですが、地面の調査で正体不明の機械を発見しました。
  • 機械について詳しく知る人は殆どおらず、どう撤去するべきかわかりません。

WWA COLLECTION 2 の作品収録や今後の予定について

WWA COLLECTION 2 のゲームボリュームに収めるには大きすぎるため、前編と後編で分けています。

  • 前編は、機械が入っているとされている、洞窟に入るまでの活動が含まれます
  • 後編は、洞窟に入ってから撤去までの活動が含まれます

そして WWA COLLECTION 2 配信後の来年には、この作品を前編と後編を統合させて、Aokashi Home や PLiCy にも公開します!

WWA COLLECTION 2 を遊んだ方や、逆にこの作品を通じて WWA COLLECTION 2 を知った方が増えればと思っています。

この前編と後編の統合作業については、随時ブログやTwitterで発信する予定です。いつ公開するかは分かり次第お知らせします。

余談

この作品に関する裏話を、ゲームのプレイに影響しない範囲でお話します。

  • この作品を構想したのは概ね3, 4年前。WWA作品の集大成として考えてはいたものの、完成度を高めるために何しようかと考えることしかしていなかったため、制作が遅れました。
  • 舞台は、自分のあるゲームの舞台と隣接しています。その答えは、 Aokashi Home や PLiCy への公開後で明らかになります。
  • 一部の街には、実在の地域をモデルにしています。名前で分かるかな?

ちなみに、 WWA COLLECTION 2 の発表に合わせて、 PLiCy さんと協力して紹介ページを作成しました。今回はトップ画面に収録作品の画面を集めましたので、コレクション作品だと一目で分かると思います!

WWA素材に路面電車を追加!

Aokashi HomeWWA素材に新しい素材が加わります!

新素材 路面電車

街と街の移動として、路面電車が必要なことから制作しました。あ、鉄道とかバスとかでも良かったんですが、時代設定上、路面電車を景観として入れたかったんです。

素材は Aokashi Home のWWA素材ページ からどうぞ。タグ「路面電車」から探すことができます。

ついでに、路面電車を走らせるための路面軌道も追加しています。電停は後ほど追加する予定です。

扱い方

画像素材にある路面電車を、使用するWWAのイメージ画像に貼り付けて、WWA側では各マスを使用して物体パーツを作成します。

  • この素材は列車と違って伸ばしたり縮んだりすることはできません
  • 冷房装置やパンタグラフを消したり、開閉演出を加えたりしたい場合は、画像素材内に専用のチップがありますのでそちらをご利用ください
    • ただし、一部の画像素材では、パンタグラフを消すことができません

各素材の特徴

f:id:aokashi:20191217005213g:plainf:id:aokashi:20191217005217g:plain
路面電車を使用したサンプル

  • 19Tram-1.gif ... アイボリー1色の車体に、1つ目の前照灯が特徴。昭和レトロを感じさせるデザインです。前照灯の位置はお好みでどうぞ。
  • 19Tram-2.gif ... 清潔な白い車体にグレーとオレンジを組み合わせた箱型路面電車。いわゆる軽快電車で、大都市の路面電車では廃止が相次ぎ、実用的な路面電車として開発されたという設定です。なぜかここだけ前方のドアが引戸になっています。
  • 19Tram-3.gif ... 近年話題のLRT方式の路面電車です。超低床電車なので、車内のステップで頑張って上ったり、降りる際にこけて転んだりする必要はありません。3つの車体で構成されていて、真ん中の車両には台車が入っていません。

これらの車両は、実世界の路面電車をモデルにして、いくつか変更を加えながら制作しました。ちなみに、そのモデルになった路面電車一度も乗っていません! (広島とか愛媛に行きたい・・・)

その他の更新情報

Aokashi Homeで更新された情報を下記に掲載しています。

  • WWAページ
    • WWA Wing の対応切り替えをした後に別のページに進んで戻ると、対応切り替えが連動しない不具合を修正しました。
    • Thanks の「天使の血・悪魔の涙」に画像素材を使用した表記が無いため、追加しました。

余談

遠くないうちに、WWAの新作を出す・・・のかも・・・? (路面電車を使用したサンプル画面がヒント)

Aokashi Home を GatsbyJS で再構築しました

これまで Aokashi Home は2017年3月から HUGO で静的サイトを生成していましたが、 GatsbyJS で静的サイトを生成する形に切り替えました。

  • スクリーンショットはすべて開発中のものです。
  • GatsbyJS で発生したエラーとその解決策について見たい場合は、「実装で躓いたところと解決策」からご覧ください。

経緯

そもそもなぜ再構築したのかは、下記の理由があります。

  • 当時手間で不安定だったデプロイの手法を、簡単で確実なものにするため
  • ポートフォリオの作成が必要になったため
  • 今のスキルを活かして、扱いやすいユーザー体験を実現したいため
  • React の勉強をしたかったため

といったことが重なり、せっかくの機会なので、Webサイトを作り直しました。

デプロイ手法について

以前は下記の方法でデプロイをしていました。

  • Webサイトを編集し、GitHubにプッシュ
  • GitHubと連携しているwerckerがプッシュを検知して、HUGOでWebサイトをビルド
  • そのWebサイトのデータを rsync コマンドを使用してVPSにデプロイ

ただし、この方法には、下記の懸念点がありました。

  • rsync でのデプロイ先にはサイトのリポジトリに存在しないWWAのマップデータやHTMLファイルが含まれるため、 rsync コマンドの delete モードが使用するとWWAが消えてしまう (→ 【rsync】コマンド(その1)――ファイルやディレクトリを同期する)
    • リポジトリWWAのマップデータやHTMLファイルを含ませる方法が手っ取り早いが、WWAのイメージ画像ファイルには他者が作成したイメージ画像が含まれていて、その画像ファイルを自由にダウンロードできるリポジトリに含ませたくなかった
  • rsyncdelete モードを切ってデプロイした場合だと、Webサイトで削除が発生した分が反映されない

スキルを生かしたユーザー体験

f:id:aokashi:20191130221157p:plain
以前のWebサイトでは、トップへ戻るボタンや目次の表示切り替えがありました。

以前のWebサイトでは、 jQuery を使用してトップへ戻るボタンを実装していましたが、後に jQuery の使用を取りやめ、 JavaScript を含ませない状態で Web サイトを運用していました。

その関係で、トップへ戻りづらかったり、目的のコンテンツが簡単に探せなかったりしたかもしれません。

React の勉強

今回使用した GatsbyJS は React でレンダリングするWebページを生成できる「静的サイトジェネレーター」の一種です。React で使用できるコンポーネントを、この GatsbyJS でも使用することができます。

今後ツール開発で React を使用することがあって、その勉強として GatsbyJS を選びました。

ちなみに、以前は同じJavaScriptのビューフレームワークである Vue.js を利用した Gridsome で再構築していました。

トップページ

f:id:aokashi:20191130011119p:plainf:id:aokashi:20191130011137p:plain
それぞれPCとスマートフォンの表示。

前回の投稿 から大きく変更しました。PCでは広々とした空間を、スマートフォンでは扱いやすさをコンセプトに配置し直しました。

PCのレイアウトを大きく変えた理由は2つ存在しています。

  • 10年くらい前に閲覧した、コンテンツのメニューを端に寄せて中央のコンテンツを大きく見せるWebサイトの配置に感動した覚えがあって、それに影響を受けた
  • 最近のWebサイトだとデバイスのサイズ分のトップ画面があって、それに追従するため

下部には最新のブログ記事と自分の各SNSへのリンクが設置されています。FontAwesome でアイコンがある場合はそのアイコンが使用されます。ちなみに、 FontAwesome は react-fontawesome を使用しました。

github.com

トップページは下へスクロールすると、自分に関する説明が表示されます。ただ、スマートフォンだとスクロールを促すような演出が無いので、自分に関する説明を見ないまま別のコンテンツに進んでしまうかもしれません。現状の課題点ですね。

レイアウト

トップページ以外のレイアウトについては、下記のように変更しました。

f:id:aokashi:20191117010735p:plainf:id:aokashi:20191117010848p:plain
PCではCoden Cityで採用された左メニューレイアウトを採用。懐かしい!

なお、最下部には「トップへ戻る」ボタンが配置されています。

ポートフォリオについては、画像があるとカルーセルが設置されます。カルーセルは pure-react-carousel を使用しました。スタイルシートが自由に調整できるのでおすすめです。

github.com

GatsbyJS は、公開されている React のコンポーネントパッケージが自由に利用できるところが良いですね。

コンテンツ

コンテンツは下記のように変更しました。

また、トップページでは、これに加えて、外部サイトであるブログと WWA FanSquare も含めています。

ポートフォリオは、インターネットを始めた頃から現在までの間に制作したものを集めました。昔のコンテンツをまとめていたことは昔もありましたが、場所が分散していました。今回のポートフォリオで分かりやすくまとめられて満足しています。

廃止したコンテンツについて

  • お知らせ ... ブログや Twitter で随時告知しますのでそちらをご確認ください。
  • おすすめサイト ... 今の個人サイトにリンク集を掲載する習慣が無いことと、以前掲載していたWebページがアクセスできなくなったため、しばらく公開を取りやめます
  • Portable Launcher 紹介サイト ... GitHubリポジトリを紹介ページにしても良さそうなので、今回の再構築では含めませんでした
  • Playing と Making ページそのもの ... サイト管理が難しくなった関係で廃止になりました

ちなみに、過去のWebサイトについては、ポートフォリオの各ページで見ることができます。

URL の変更について

以前は一部ページのURLで .html が含まれていました。

  • 当サイトについて: about.html
  • 各素材ページ: materials/*.html

ただ、 .html を含めないほうが URL を間違えないので、全ページ .html を省略しました。

また、WWAJavaアプレットの起動方法については、資料集に移転しています。

スタイルシート

スタイルシートも変更を加えました。フレームワークBulma を採用しました。WWAや素材、ポートフォリオの各項目にBulmaのBoxを使用しています。

Bulmaに決めた理由としては、下記の理由が挙げられます。

  • Bootstrap ... 構築してしまうとBootstrap臭がしてしまい、Webサイトのオリジナリティを失う
  • Tailwind CSS ... sassとの相性が悪い
    • text-smp-4 といった、CSSの記述で済ませられるクラスが多数用意されていて、これを使用すると sass を使用する意味が無くなる
    • 実はWebサイトのリニューアルの目的の1つとして、 sass を使用したWebサイト構築が含まれている
  • Bulma ... sass で構築している関係で sass を使用することが可能で、変数の調整でカスタマイズが可能

いかにフレームワークっぽさを感じないで、sassの特徴を発揮できるか模索した結果です。

ただし、Bulmaを使用した場合でもカスタマイズの幅には限界はあります。ポートフォリオの各ページにある「〇〇とは」の項目は、本来なら枠線を付けたかったのですが、タイトルを含めると枠線が無効になるため、仕方なく枠線無しで表示しています。今後のアップデートに期待ですね。

f:id:aokashi:20191116144841p:plain
〇〇とは(AboutNote) の表示

ちなみに開発に掛かる時間を短縮するために、オレオレフレームワークの廃止を目標としましたが、前述のフレームワークの選定のために逆に時間を費やしてしまいました。

なお、ページ全体のレイアウトについては、グリッドレイアウトを使用したいことと、フレームワークだけでは限界があることから、フレームワークのクラスはあまり使用していません。

ホスティング

Aokashi Home 自体は Netlify でホスティングしておきたかったのですが、ここはWWAのランキングCGIの関係上、ホスティングは引き続きVPSにしました。ただし、VPSの中身も作り直しました。

  • 以前
    • CentOS 7 を使用
    • Apache を導入していて、ドキュメントルートは www.aokashi.netcontents.aokashi.net で違う
    • デプロイはクラウド上の wercker が行う
  • 今回
    • Ubuntu Server 18.04 を使用
    • Docker を導入
    • docker-compose-letsencrypt-nginx-proxy-companion リポジトリを使用していて、www.aokashi.netcontents.aokashi.net をコンテナで分けている
    • なお、 www.aokashi.net は NGINX + fcgiwrap 、 contents.aokashi.net は従来と同じく CentOS 7 + Apache の構成になっている
    • その上、ドキュメントルートはリクエストの location によって異なる
    • デプロイは現時点では手動だが、後に Jenkins や Concourse をVPS内で導入し、デプロイを自動化するつもり

github.com

f:id:aokashi:20191130160721p:plain
ドキュメントルートの事情をまとめるとこんな感じ。

docker-compose-letsencrypt-nginx-proxy-companion は .env ファイルを作成して立ち上げておくと、あとはコンテナに環境変数を与えるだけで HTTPS 対応のサイトが出来上がります。 Let's Encrypt 証明書を certbot で取得したときは入力に手間がかかりましたが、ここまで簡単過ぎてびっくりしました。

実装で躓いたところと解決策

再構築するにあたって躓いたところと解決策についてです。

絞り込み機能が実装できない

GatsbyJS は markdown ファイルや YAML データの取り込みに GraphQL というクエリ言語を使用しています。 GraphQL を利用することで、出力されるデータのフォーマットが分かりやすくなったり、 filtergroup といった SQL で使用していた絞り込みやグルーピングを使用することができたりします。

WWA素材やポートフォリオで、タグによる絞り込み機能を実装しようとした場合、下記のようなことをついしてしまいがちです。

const data = graphql`
query WWAMaterialDataQuery {
  allWwaMaterialYaml(filter: {tags: {in: "${this.state.tagBy}"}}) {
    nodes {
      name
      file
      description
      publishedAt
      tags
    }
    group(field: tags) {
      fieldValue
    }
  }
}
`

これだと String interpolation is not allowed in graphql tag とエラーが発生してしまい、動作しません。

GraphQL のクエリは GatsbyJS のページ生成時 (gatsby build とか) にしか処理されないため、ユーザーの操作で変わってしまうプロパティやステートの変数はもちろん、予め定義した定数でさえも割り当てることができません。

今回の絞り込み機能は、データを出力するメソッドを実装して絞り込みを行ったり、タグ毎にタグ一覧ページを作成したりして解決しました。

const data = graphql`
  ...
`

const WWAMaterialData = data.AllWwaMaterialYaml.nodes.filter(
  node => node.tags.includes(this.state.tagBy)
)

パスに # を含むページがビルドできない

これは、ポートフォリオページにタグ機能を実装する際に発生しました。

ポートフォリオの各項目に付いているタグを取得し、そのタグごとに項目一覧のページを生成する流れをしていました。しかし、動作確認用で使用している Netlify でビルドが失敗してしまい、ログを確認したところURLの禁則文字がパスに含まれていました。

実はポートフォリオの各項目のタグに C# を与えていて、 # が原因で正常にページが生成できていなかったようです。

f:id:aokashi:20191130162438p:plain
画面のように、ページ一覧には C%23 となっていても、 404 が返ってきます

上記の事情がありましたので、仕方なく C#C_Sharp という名前に変更する形で解決しました。どうしても # を含めたい場合は ♯ のように全角にする手もあります。

ちなみに、Wikipedia でもURLの禁則文字をページタイトルに含めることができないため、C# では C_Sharp という名前になっています。

しかし、どうしてプログラミング言語の名前に禁則文字を含めるんですかね。

ポートフォリオの frontmatter の日付が日付として認識してくれない

frontmatter とは、Markdownページの先頭にあるプロパティを記述した箇所です。

---
path: /portfolio/wwa_game
template: portfolio-item
date: "2010-02-21"
title: WWAゲームの制作
season: junior-high-school
tags:
  - WWA
images:
  - path: /portfolio/wwa_game/making_wwa_2010.png
    alt: 2010年頃のWWAゲーム制作の様子
    description: 初期のWWAゲームの制作の様子です。
---
--- の上にあるのが frontmatter です。

このうち、日付を記述するためにdateを設定しました。実はGatsbyJS の GraphQL では日付のフォーマット (YYYY-MM-DDThh:mm:ss とか) になっていれば日付として認識され、 GraphQL で日付を取得する際に下記のようにを記述すればフォーマットを変更することができます。

frontmatter {
  path
  title
  tags
  date: (formatString: "YYYY月MM日DD日", lang: "ja-JP")
}

しかしながら、ポートフォリオの項目をひたすら増やしていると、Unknown argument "formatString" on field date とエラーが表示されてポートフォリオが機能しません。これは、日付として GraphQL が認識していないことでしょう。

自分のサイトのリポジトリのコミットを見ていると、一部の項目で日付のフォーマットを満たしていない記述が見つかりました。ただし、修正しても認識してくれないため、下記のように実装を変更しました。

  1. formatStringlang の使用を諦める
  2. 代わりに、日付を引数にフォーマットを変更するメソッドを定義し、フォーマットを変更したい場合はそのメソッドを利用する

Element type is invalid のエラーが発生している

この不具合の原因は、 importexport で間違いがあります。

import graphql from "gatsby" // { } で囲っていない

const header = ({ children }) => {
  return (
    <header>
      ...
    </header>
  )
}

// export default ... が無い

Invalid Hook Call のエラーが発生している

Invalid Hook Call というのは、 React の Hooks 機能に関わる不具合ですが、 React の Hooks 機能を使用しなくてもこのエラーが発生することがあります。

この不具合の原因の一つとしては、下記のようにクラスコンポーネントuseStaticQuery を使用していることです。

class WWAMaterialPage extends React.Component {
  render() {
    const data = useStaticQuery(`
      ...
    `) // Invalid Hook Call
  }
}

useStaticQuery メソッドはクラスコンポーネントでは使用できません。StaticQuery コンポーネントを使用する必要があります。

class WWAMaterialPage extends React.Component {
  render() {
    return (
      <div>
        <StaticQuery
          query={graphql`
            ...
          `}
          render={ data =>
            <>
              ...
            </>
          }
        />
      </div>
    )
  }
}

なお・・・クラスコンポーネントでなければいけない理由の一つとして、ステートを使用したいことが挙げられますが、1つか2つぐらいしかステートを使用しなければ、 React の Hooks 機能を使用する手もあります。

const WWAPage = () => {
  // onlyWWAWing がステートそのもの、変更したい場合には checkOnlyWWAWing(値) を使用する
  const [onlyWWAWing, checkOnlyWWAWing] = useState(false);
  const data = useStaticQuery(graphql`
    query {
      ...
    }
  `)
  return (
    ...
  )
}

再構築後の予定について

  • 後にCIを導入し、デプロイを自動化する予定です
  • 資料集については引き続きPukiwikiで運用を続けますが、遠くないうちに当サイトの一部としてGatsbyJSに取り込む予定です
  • ポートフォリオについては、就職して落ち着いてきたら資料集に統合して、次追加されるコンテンツのスペースを確保するつもりです
  • 廃止したお知らせは、どこかの場所で保管するつもりです
  • 実は、 WWAのランキングCGIの関係上 と言っておきながら、ランキングCGIがまだ稼働できていません
    • 遠くないうちに修正する予定です
    • ただ、WWAのランキングは Java アプレットWWAからじゃないと登録できないし、もう廃止しても良いのではと思ってしまう

今回のWebサイト構築で、Apache で普通のHTMLを動かすサイトから、NGINX 上で React で動作するサイトへと変化しました。今思うと 変化しすぎたなあー と感じています。研究活動や就職活動で支障が出ないように調整したため、消えてしまったコンテンツ (特にお知らせのアーカイブ) もありますが、近いうちに何かしらの形で残そうと思います。

ちなみに4年前は MODX 、2年前はHUGOでWebサイトを作り直したので、2年毎に作り直ししているんですよね。今回の GatsbyJS での再構築でだいぶ疲れてしまったので、ここ数年は GatsbyJS とお世話になろうかなと思います。

12月になったところですが、これからなにか発表できるものがあるかもしれません。今後もよろしくお願いします。

参考記事

akabeko.me

lab.unicast.ne.jp