
マイケル
みなさんこんにちは!
マイケルです!!

エレキベア
こんにちクマ〜〜〜

マイケル
この度、WordPress製だった当ブログをNext.jsで作り直しました!
前回まででWordPressのデータ移行・表示まで完了したため、今回はMarkdownによる執筆環境の構築について紹介します。

【都会のエレキベア】ブログを大幅リニューアル!WordPressからNext.jsに移行するまでの流れをまとめる
2024-01-01

【Next.js】第一回 WordPressブログをNext.jsに移行する 〜全体設計、環境構築編〜
2023-12-31

【Next.js】第二回 WordPressブログをNext.jsに移行する 〜WordPressデータの移行・表示編〜
2023-12-31

【Next.js】第三回 WordPressブログをNext.jsに移行する 〜Markdown執筆環境構築編〜
2023-12-31

【Next.js】第四回 WordPressブログをNext.jsに移行する 〜サーバ移行・SEO・広告設定編〜
2023-12-31

エレキベア
あと一息で新体系のブログが開発完了するクマ

マイケル
これまでMarsEditというツールを使用してブログを書いていました。
WordPressやMacOS依存な点は微妙でしたが、ショートカットや画像アップロードといった記事の執筆作業に関しては快適で、それ以上の執筆環境に改善したいという目標がありました。

▲WordPress時代はMarsEditを使用していた

エレキベア
MarsEditはよくできたツールだったクマね

マイケル
・Windows/Mac両対応で使えるようにしたい
・Markdown形式で執筆したい
・画像をドラッグ&ドロップでアップロード、リサイズしたい
・ホットリロードに対応したい
今回はこれらの要件を満たす環境を作ることを目指しました。
最終的に、VSCode上で下記のような形で執筆できるようになりました。

▲ホットリロードによるMarkdown記事執筆

エレキベア
おお〜〜〜〜
いい感じに執筆できてこの独特なブログにも対応できてるクマ〜〜

マイケル
めちゃくちゃ執筆しやすくなって気持ちいいね!
ただ画像のリサイズやアップロードに関してはVSCodeの機能で対応できそうになかったから、Electronで別途ツールを開発して対応しました。

▲画像アップロードは別途ツールを作成

エレキベア
だいぶ本格的な執筆環境が整ったクマね

マイケル
今回はこの開発環境周りの構成について紹介していきます!
また、コードについても公開できる範囲でGitHubに上げているので、こちらも合わせてご参考ください!
GitHub - nextjs-elekibear-blog-scripts

エレキベア
中々なボリュームクマ・・・
Markdown変換処理の実装
Markdown変換ライブラリのインストール

マイケル
まずはMarkdownファイルのReactElementへの変換処理についてです。
こちらは react-markdown をメインで使用することにしました。
合わせて、Markdown内にカテゴリ情報や日付情報等も付与できるようにするため gray-matter も使用しています。

エレキベア
どちらも定番のライブラリクマね

マイケル
これらのライブラリを下記コマンドでインストールします。
今回はテーブル表示、HTML記述も行えるようにするため、remark-gfm rehype-rawも合わせて導入しました。

エレキベア
これで準備は完了クマ
Markdown変換処理の実装

マイケル
Markdownは下記形式で記述することにしました。
「---」で囲んでいる部分がgray-matterによる付加情報の指定部分になります。
▲gray-matterで付加情報を追加した状態

▲変換して表示した状態

エレキベア
Markdown内の情報で記事の執筆が完了できるようにしたクマね

マイケル
この変換処理について、まずMarkdownファイルの読込処理は下記のようになっています。
格納フォルダ内のMarkdownファイルを全て読込、ファイル名をslugとして管理することで、WordPress記事で使用していたmst_postsは不要になっています。
▲Markdownデータの型定義
▲Markdownファイルの読込処理
▲Markdownデータの変換処理

マイケル
あとはこのAPIから呼び出したMarkdownデータを、既存のテキストデータと合わせて表示するよう実装するだけです。
▲記事ページでのMarkdownデータ読込処理
▲Markdown記事のコンポーネント

エレキベア
これでMarkdown記事の表示もできたクマね

マイケル
ここで記載しているCustomブロックについては、この後紹介する目次抽出とカスタム記法の記述にて解説します。
目次要素の抽出

マイケル
目次要素を抽出するにはどうすればいいか?については悩みましたが、
変換時に見出し要素を抽出、idを生成してStateに設定する
方法で実装することができました。

▲記事内に表示する目次要素

マイケル
少々無理矢理ではありますが、実装内容は下記になります。
▲記事ページにて目次情報設定用のStateを作成
▲ReactMarkdownのカスタムブロックにて見出し要素の抽出とid付与を行う
▲作成したStateをContext経由で渡し、設定されたら目次を表示する

マイケル
ReactMarkdownのカスタムコンポーネントにStateを渡す方法が見つからなかったため、Context経由で無理矢理渡して更新する実装となっています。
他にいい方法があれば教えてください・・・

エレキベア
まあこればかりは仕方ない気はするクマ・・・
執筆環境の改善

マイケル
以上で記事の表示は完了ですが、使い心地をよくするために
・画像ファイル周りの工夫
・吹き出し等のカスタム記法の対応
・キーボードショートカットによる入力
を追加で対応しました。
執筆中の画像ファイルの扱いについて

マイケル
まず画像周りの運用をどうするか?についてです。
画像ファイル周りは別のサーバで管理しているのですが、開発中はサーバにアップロードせずにローカルで管理したかったので、執筆中のみpublicフォルダ内で管理することにしました。
具体的には下記のような構成です。
▲一時的にpublicフォルダに格納する

マイケル
/server-contents/public配下の資産がサーバへのアップロード対象になります。
記事執筆の完了後、アップロード処理と記事内のURL書き換えを行うようにすれば対応できそうです。
URL | |
---|---|
アップロード前 | /server-contents/public/XXX |
アップロード後 | https://content.elekibear.com/XXX |

エレキベア
なるほどクマ
それならローカルでの執筆ができそうクマね
カスタム記法に対応する

マイケル
次にMarkdownでのカスタム記法の記述対応についてです。
例えば←のようなキャラクターが喋っている吹き出しなどですね。

エレキベア
この辺のカスタマイズは簡単にできるクマ??

マイケル
unifiedというのを使ってMarkdownを拡張するのが王道みたいだけど、中々面倒そうだったので今回は下記で紹介されているコードブロックをカスタムして表示する方法を採用しました。
Qiita - オレオレ記法のMarkdownを任意のReactElementとして変換する

エレキベア
なるほどクマ
これなら簡単にカスタムできそうクマ

マイケル
吹き出しを例にすると、例えば僕が喋っている「マイケル吹き出しコンポーネント」は下記のように記載するとします。
▲コードブロックの記法にパラメータを追加している

エレキベア
通常のコードブロック記法に「talk:m:1」を指定しているクマね

マイケル
この指定をコード側で受け取るために、下記のようなカスタムコンポーネントを作成します。
Markdownで「```」の後に指定された文字は「language-XXX」の形式でクラス指定されるため、そこから文字列を受け取っています。
▲コードブロックのカスタム処理

マイケル
あとは受け取ったパラメータをコンポーネントに渡して表示するのみ!
吹き出しコンポーネントは下記のようになっています。
▲キャラ吹き出しコンポーネントの実装

マイケル
このようにすれば割と柔軟にカスタムで追加することができます。
整理すると当記事は下記のようにして記述しています。
▲Markdown記事執筆例

▲Markdown記事を表示した状態

エレキベア
この記事の実態はこんな感じになっていたクマか・・・
キーボードショートカットで入力できるようにする (VSCode)

マイケル
カスタム記法を入力できるようにしたのはいいですが、これを毎回手動で入力していると大変です。
そのため今回はVSCodeのキーボードショートカット機能を編集する形でショートカット入力できるように対応しました。

エレキベア
さすがVSCodeクマ〜〜〜〜

マイケル
キーボードショートカット設定は下記手順で開くことができます。
開いたkeybinding.jsonの内容を編集することで設定できます。

▲Preferences > Keyboard Shortcuts からショートカットメニューを開く

▲右上のファイルマークをクリックすると開ける

マイケル
吹き出しコンポーネントの例として下記のように設定しました。
しかし、keybinding.jsonは現状ワークスペース単位での設定ができないようだったため、今回は .vscode/settings.jsonでフラグが指定された時のみショートカットを有効にするよう対処を行いました。

エレキベア
ワークスペース設定でフラグを設定する方法があるクマね
まあそもそもワークスペースに対して設定できるようにしてほしいクマ・・・(要望)
執筆に必要なツール類の開発
執筆用デスクトップアプリの作成

マイケル
以上でだいぶ快適な執筆環境になってきましたが、まだ下記の課題が残っていました。
・画像のアップロード、リサイズが面倒くさい
・カテゴリ、タグの指定が行いにくい

エレキベア
うーん、確かにこの辺は難しい問題クマ・・・

マイケル
この二点についてはVSCode上での対応は難しそうだと判断したため、Electronを用いて専用のデスクトップアプリを開発することにしました。
画像リサイズツール

カテゴリ編集ツール


エレキベア
おおぅ・・・
ここまで作ったクマか・・・

マイケル
詳細については下記の記事にそれぞれまとめているため、興味がある方はご参照ください!

【Electron × Vue3】画像をリサイズして任意の場所に保存するツールを作る
2023-12-31

【Electron × Vue3】カテゴリ情報のCSVデータを操作するツールを作る
2023-12-31

エレキベア
Electronでの開発も中々面白いクマね
記事作成・アップロードスクリプトの作成

マイケル
そして最後に記事作成・アップロードの処理についてはshellで記述しました。
執筆開始時 -> create_new_post.sh
執筆完了時 -> upload_new_post.sh
をそれぞれ実行する方向で対応しています。
▲記事作成スクリプト
▲記事アップロードスクリプト

エレキベア
記事作成時はテンプレートを元に作成、
アップロードでは画像のアップロードとURL書き換えを行っているクマね

マイケル
アップロード完了後、差分を確認しつつgit pushすれば執筆が完了するフローです!
ホットリロード編集できるようにする

マイケル
最後に、Markdown記事を編集した際にホットリロードで表示を更新する方法について紹介します!
こちらは下記の記事を参考にさせていただきました。
参考:
Next.jsでMarkdown記事の快適なホットリロードを実現する

マイケル
Next.jsとは別にExpressプロジェクトを作成し、その中で chokidar を使用してファイルの変更を監視する手法です。
実装はシンプルで、下記のようになっています。
▲chokidarによるファイル変更監視
▲ファイル変更監視の設定

マイケル
ファイル変更が監視されたらpostMdChangeイベントとして変更内容を通知するよう実装してあります。
このイベントをNext.js側でsocketを経由して受け取り、コンテンツ表示を更新するようにすれば実装完了です。
▲記事ページのスクリプトで変更されたファイル内容を受け取る

エレキベア
ホットリロード用のプロジェクトを別途作成したクマね
これは中々便利クマ〜〜
おわりに

マイケル
というわけで今回はMarkdownによる執筆環境の構築についてでした!
どうだったかな??

エレキベア
画像アップロード、ホットリロード編集まで独自で実装できて楽しかったクマ〜〜
自分で作ると痒いところに手が届くからいいクマね

マイケル
これからも執筆しながら少しずつ改善していく形になるだろうね
とりあえずは当初の目標としていた環境のレベルは実現できたから、今の所満足です!

マイケル
三回に分けての記事となり長くなりましたが、WordPressからNext.js移行についての記事は以上になります!
最後まで見てくださった方はありがとうございました!

エレキベア
この数ヶ月でいろいろなことができて楽しかったクマね
フロントエンド技術がだいぶ分かるようになってきたクマ

マイケル
しばらくWebメインで触ってきたので、改善したブログも活かしながらまたゲーム開発に戻っていろいろと遊んでいこうと思います!
アデューー!!

エレキベア
クマ〜〜〜
【Next.js】第三回 WordPressブログをNext.jsに移行する 〜Markdown執筆環境構築編〜 〜完〜

【都会のエレキベア】ブログを大幅リニューアル!WordPressからNext.jsに移行するまでの流れをまとめる
2024-01-01

【Next.js】第一回 WordPressブログをNext.jsに移行する 〜全体設計、環境構築編〜
2023-12-31

【Next.js】第二回 WordPressブログをNext.jsに移行する 〜WordPressデータの移行・表示編〜
2023-12-31

【Next.js】第三回 WordPressブログをNext.jsに移行する 〜Markdown執筆環境構築編〜
2023-12-31

【Next.js】第四回 WordPressブログをNext.jsに移行する 〜サーバ移行・SEO・広告設定編〜
2023-12-31