S.F. Page

Programming,Music,etc...

途中経過 - jekyllのような静的ブログジェネレータをnode.jsで作る(2)

静的ブログジェネレータはぼちぼちと作っている。そのせいで、ブログの更新も滞りがちだ。。

作成は、下記の各フェーズの設計・コード書きを同時並行で進め、完成に近づけていく。

  1. ブログデザインを作る
  2. はてなAPIで吸い出したデータをいったんmarkdown形式のデータでエクスポートするコードを書いてデータをエクスポートする
  3. それをHTMLに変換するコードを書いて、ローカルでテスト
  4. ローカルでのテストの区切りのよいところで、さらにテストサイト(https://blog-test.sfpgmr.net/)にアップしてテスト

今回の静的ブログジェネレータの成果物は以下
https://github.com/sfpgmr/www/tree/master/wwwmaker

今のところのテストサイトの状況は以下
https://blog-test.sfpgmr.net/entry/2017/06/18/162009

とりあえずはてなAPIの全記事を単独ページに変換するところまでのコードを書いたが、私の記事はmarkdown+はてな独自記法となっていて、まだはてな独自記法のケアまではできていない。方針としては、markdown記法におきかえることができる部分はmarkdownに変換するつもりだ。

その他いろいろやらんといかんので、完成までには1か月以上はかかるだろうなぁ。。

jekyllにヒントに、静的ブログジェネレータをnode.jsで作ろうと思う

動機

おとといくらいからまたブログの引っ越しをしたくなってきたのである。 前からやろうとして果たせていないことだけど。

私は

  • 完成したブログ・システムを構築できるほどの高いモチベーションはない。が、「出来合いのもので満足できない機能があれば手を加えて改良したい」・「得た知識・技術をブログ・システムに反映したい」という思いはある
  • プログラミング・スキルが少々あり、頑張ればやりたいことがなんとか実現できる

という人である。こういう人にとって「はてなブログ」はいささか物足りない。

普通私のような人であればカスタマイズ可能なブログ・システムを選択する。例えば、Wordpressなどである。Wordpressはオープン・ソースであり、本体をいじるのみならずプラグイン・システムで必要な拡張を容易に行うことができる。自由度は非常に高い。実際「はてなブログ」の前は自サーバー1台でWordpressを運用していた。 しかし、Wordpressは非常にfatなシステムである。自分のやりたいことを表現するにはWordpressの内部構造を理解するためかなりの労力を払わなくてはならず、すくなからずその労力が、本来自分がやりたかったことをやる労力を上回ることがしばしばである。しかもベース言語はPHPであり、node.jsではない。さらにはデータストアにRDBMS(MySQL)を使わねばならず、そのリソース確保やメンテが煩わしい。そういうことに疲れてしまい、本来やりたかったことへのモチベーションがそがれてしまうのである。

上のようなことがあって「はてなブログ」に引っ越した。「はてなブログ」は有料オプション「Pro」であればカスタマイズの自由度が上がるので、ある程度私の欲求を満たせるかなあと思ったのだ。

「はてなブログ」に引っ越したのはもう1つ理由がある。それはアクセスアップである。「はてな」様のプロモーション力によって、ブログを移行するだけでアクセスアップが見込めると思ったのである。しかし思ったほどではなかった。というかほとんど変化がなかった。「はてなブログ」のメリットは「はてなブログ」トップページの更新情報に載ることと、「はてなブログ」が持つSEO力である。コンテンツが広く人に知れ渡るようにするためにはやっぱり記事の質が重要である。質がが高ければブックマークされたり、SNSで拡散されるのである。いくらはてな様のご威光でも、質の低いコンテンツは拡散されることはないのである。私のコンテンツには拡散しうるに値する質的要件を満たしていないということが、「はてなブログ」への移行によってはっきりした。さらには「カスタム・ドメイン」を使用したことによって、「はてな」様のドメインパワーがなくなってしまい、結果SEO力が失われていることも追い打ちをかけていると思われる。
しかしWordpressで運用していた時もブクマが結構ついたりして、アクセスが増えてきたところで「はてなブログ」に移ってブクマが全部消えて一時的にアクセスダウンしたりとか、「はてなブログ」でちょこちょこブクマがついてきたときに「カスタムドメイン」に移行したりだとか、「アクセスアップ」にこだわりがあるかというと、そうではなかったりするのが私の不思議なところではあるのだが。。

そういうわけで「はてなブログ」に移ってもメリットはなく、改良欲求を満たすこともなく、「はてなブログPro」の月額コストをかける意味もないので、移行1年後くらいから引っ越したくなった。しかし、やっぱりブログを引っ越すのは結構手間がかかる。面倒だからこれでいいか..。と何度か踏みとどまってはいた。が、今私が使っている自作のデザイン・テンプレートのcss部分が巨大なせいで「はてなブログ」のエディタでは編集できなくなってしまい、リニューアルできなくなってしまった。これもまあ私が悪いのだが。。ただ今のままでは一生このままなので、新しいブログを作ってそこに引っ越すしかないなーという点も引っ越しのモチベーションを高めることになり、今回ほぼ引っ越しすることを決心した。ただWordpressに戻るというのもなんだし、できれば私のお気に入りのnode.jsベースで私に合うような軽いブログシステムはないだろうかと調べもしたが、望むものはなかなかなかった。hexoなんかもよい感じがするんだけど、ちょっと違う。

それでjekyllを眺めているときに、こちょこちょっとnode.jsで作れば望みのものができそうだなと考えた。

望みのものとは、

  1. markdownもしくはHTMLなどで文書を書き、所定のディレクトリに保存する。エディタはvs codeを使用する。
  2. nodeで文書をHTMLでレンダリングする。
  3. レンダリングしたものをgitを使って自サーバーにデプロイする。

である。つまり「node.jsで作られた静的ブログジェネレータ」である。1.は出来合いのものであるし、3.はすでに構築済みである。

blog.sfpgmr.net

なので2.だけを作ればよい。

しかしこれはほぼjekyllそのままである。。そうなのだが、jekyllはrubyで作られているのですよ。。 それでjekyllをお手本として2.の部分のコードを書こうと思い立ったわけである。というわけで早速仕様を考えつつ、コードを書き始めた。 これが完成した暁には、「はてなブログ」を引っ越そうと考えている。つまりジェネレータが完成しない限り引っ越しは行わない。なので今までの私の制作物にみられるような「中途半端に投げ出す癖」によってこのままずっと「はてなブログ」を使い続けることもありうる。。

仕様に関して

記事

1記事1ファイルとして、特定のディレクトリに保存することにする。ファイル名は何でもよいことにしようと思う。文書はmarkdownで記述することにする。またブログ公開に必要な属性情報(公開日やタイトル、カテゴリ、作者)をファイル中に記述することにする。jekyllでは、YAML Front-matterというので属性を記述する。

---
layout: post
title: Blogging Like a Hacker
---

私はこれをjson-ldで書こうかなと思っている。正確に言うと、shcema.orgのコンテキストを前提として、属性を記述するのである。ただしjson-ldで書くと情報が冗長になり、それは手間なので、断片的に書けるようにフォーマットとしてはjson形式としておこうかなと思っている。タイトルは1行目に#(H1)で書くことにする。

# ここがタイトルになる
 <script type="application/json">
{
 "blogPosting": {
  "url": "https://blog.sfpgmr.net/entry/2017/06/15/184304",
  "datePublished": "2017-06-15T18:43:04+09:00",
  "dateUpdated": "2017-06-15T18:43:04+09:00",
  "dateModified": "2017-06-15T18:43:04+09:00",
  "description": "要約はここに入れる..",
  "keywords": "Music,Game,Programming"
 }
}
</script>

ブログ本文はここから書いていく。

上の例のように、<script>タグの間に属性を入れる。typeapplication/jsonとしておこう。本当はapplication/ld+jsonとしておきたいところだが、先ほども書いたようにjson-ldの断片となっているので仕方がない。この属性はジェネレータによってjson-ldとなるように@contextなどが適宜追加される。 <script>で囲んでおくと、VS Codeでプレビューしたときにこの部分が隠されるので好都合であると考えている。

この文書を公開するかしないかはdatePublishedに日付を入れるか入れないかで判断しようと思っている。属性の記述は省略することができるようにする。属性についてはschema.orgblogPostingから任意の属性を挿入できるようにしておけばいいだろう。

このようなフォーマットの文書ファイルを、適当なフォルダに置いておく。静的ブログジェネレータはそのフォルダの中身を再帰的に検索して静的HTMLファイルを生成することになる。

静的ブログジェネレータ

静的ブログ生成はnode.jsで行う。

ポリシーとしては「静的にできるものはできる限り静的に」である。例えばMathJaxを前提としてtexをドキュメント中に埋め込こめるようにした場合は、ジェネレート時にpngやsvgに展開することにする。これはレンダリング時のスピードアップを図るためである。

markdown部分のレンダリングはmarkdを利用することになるだろう。markdはコンテンツ部分のHTMLへのレンダリングを受け持つ。その結果をHTMLファイルにレンダリングするのは、ejsでやろうかなと思っている。これはすでにhttps://www.sfpgmr.net/の再構築時に作ったコードがあるので、それを流用することになると思う。あとはAMP HTMLも出力できるようにせんといかんな。。 そして上記の属性部分をパースするコードを書けばまあできるかなぁ。。と考えている。あとはカテゴリや年月日形式のリスト、サイトマップやRSSを出力するようにすればいいかなぁ、くらいで考えている。

スタイルとしてはhttps://blog.jxck.io/を参考にしたい。

Blog PingとかTrackbackとかどうするのか

これは今のところ思案中。。

その他

URLはカスタム・ドメインなので、そのままで引っ越しできる、つまりリンク切れを極力起こさず引っ越しできるかな。。と考えている。ただし移行後はHTTPS(HTTP/2)となるので、旧URLは304リダイレクトすることになると思う。

引っ越しできた暁には…

はてなブログProの月額費用を、おひとり様マストドン用VPS費用に振り向けようと思っている。マストドン自体あまり興味はなかったが、「おひとり様マストドン」が作れるとわかって、がぜん興味がわいてきている。このことも引っ越しのモチベーションになっている。といってもコミュ力に乏しい私がそんなの作ったところで、過疎サーバーがひとつできるだけだと思うけどね。。

故障に備え、ハードディスクを入れ替えた

私は過去に1TBのHDDが壊れたことがある。その時はダメ元でUltimate Boot CDで復活できるところは復活して、あとはバックアップから戻すことでほぼ復旧した。

blog.sfpgmr.net

今のところは故障なく使えているが、HDDというのは消耗品なのでいつ故障してもおかしくない。なので故障に備えておかなくてはならない。 少なくとも何年か使ったら取り替える必要がある。壊れるまで使うというのでもいいが壊れた時のストレスや復旧の手間を考えると、事前に交換しておいたほうがよいというのが、過去の苦い経験から得た教訓である。

そういうわけで、ボーナスをもらったことだし、今回ディスクを購入して、古いディスクを捨てることにした。

今までのディスクの構成は

  • ディスク0 : 2TB HDD(セカンダリOS用・作業用)
  • ディスク1 : 500GB SSD (OS用・作業用)
  • ディスク2 : 300GB HDD(データ用)
  • ディスク3 : 1TB USB HDD(バックアップ用)

であった。1TB USB HDDと300GB HDDは数年以上使っており、かなり古いので300GBのディスクは廃棄することにし、1TB USB HDDはTVの録画用ディスクとして余生を送っていただくことにした。といいつつ、過去に使用したHDDも実際のところどう廃棄してよいものか思案していて、捨てずにとったあるんだけどね。。

そしてAmazonで2TBのHDDを購入した。今回は速度と容量のバランスを考え、SSHDを購入した。SSHDというのはキャッシュとして8GBのSSDを搭載したHDDである。

これを追加し、ディスクは以下の構成で使用することにした。

  • ディスク0 : 2TB HDD(セカンダリOS用・バックアップ用)
  • ディスク1 : 500GB SSD (OS用)
  • ディスク2 : 2TB SSHD(作業用)

2台購入してBIOSレベルでRAID 1することも考えたが、そのような環境であってもバックアップは必要だし、2台買う資金はないので、あきらめた。

データの移動は、昔ながらのrobocopyを使って行った。

バックアップについてもrobocopyするバッチファイルを作って、夜間にタスクスケジューラでバッチ処理で行うことにした。robocopyのオプションで開発時の一時ファイルやディレクトリなどは除外するようにしてバックアップ容量を削減するようにもしている。

robocopy k:\webdata  z:\backup\webdata /xf *.vhd *.vmdk *.pdb *.sdf *.suo *.ilk *.vcxproj.* *.obj *.pch /xd .svn .git tmp "$RECYCLE.BIN" "System Volume Information"  temp Debug Release ipch backup E:\i_backup\download vhd ダウンロード node_modules /TIMFIX /mir /np /mt:6 /r:0 /w:0 /log:c:\copylog.log
.
.
.

タスクスケジューラでは、夜間にスリープを解除してバックアップを取るように設定している。

それで最後にスリープに移行するためのコマンドが書いてあって、バックアップが終了したらスリープするようにもしている。

rem スリープ状態に移行する。管理者権限がないと休止状態になるので注意
powercfg -h off
rundll32.exe powrprof.dll,SetSuspendState 0,1,0
powercfg -h on

wbadminを使う方法もあるが、複数ディスクを1つにまとめてバックアップを取ったり、除外ファイル・ディレクトリも使用する環境によって変えたりできる利点があるので。OSだけはwbadminで別にとることにしたけどね。

しかしまあ、Windows 10も可用性やデータの安全性を高める機能はいっぱいあって悩むね。。

  • BIOSでのRAID
  • ディスク・パーティション単位でのミラーリング・ストライピング+パリティ
  • システム・バックアップ
  • システム・修復ディスク
  • システム・イメージの作成
  • ボリューム・シャドウ・コピー
  • システムの保護(復元ポイント)
  • ファイル履歴
  • 回復パーティション

Windows 95の時では考えらないくらい充実している。