🦕

Deno(Fresh)で「Markdown で投稿できる SNS のようなもの」を作り直し、Deno Deploy で公開した

2023/01/10に公開

Leaves

Deno(Fresh) の学習がてら、Markdown で投稿できる SNS のようなものを作り、Deno Deploy 上に公開してみました。Leaves と名づけました。

https://leaves.chiba.dev/

screen

SNS にありそうな機能を含め、以下の機能を実装しています。

  • 投稿(Post) 📰
  • コメント(Comment)
  • フォロー(Follow) 👦
  • いいね(Like) 💛
  • 通知(Notification) 🔔
  • ソーシャルログイン(Google) 🔑
  • 全文検索(Search) 🔍
  • Markdown で投稿
  • 無限スクロール
  • Twitter Card と Open Graph
  • iframe でのコード埋め込みは、YouTube と Open Graph Preview に制限

Googleアカウントで認証するようにしており、ログイン時に以下のメッセージが表示されますが、メールアドレスの取得していません(これは何故メールアドレスと表示してるんでしょう。。)

続行するにあたり、Google はあなたの名前、メールアドレス、言語設定、プロフィール写真を leaves.chiba.dev と共有します。

作り直した

以前、以下のような記事を書きました。
https://zenn.dev/chiba/articles/md-sns-deno-alephjs
壊れました。
Aleph.js を利用して作っていたのですが、どうも依存のバージョンを固定しきれず、何もしていないのに壊れました(何もしていないから壊れました)。
Aleph.js より先に Fresh の方が、先に v1.0 に達してしまったので Fresh で作り直しました。
また、Heroku に deploy していたのですが、Deno で作っているということもあり、Deno Deploy に変更しました。

以降は、どう実装し起動しているのか簡単にご紹介したいと思います。

ソースコード

ソースコードも公開しています。変な部分がありましたら、コメント頂けると嬉しいです。
https://github.com/chibat/leaves

Deno

Web アプリのランタイムとして Deno を利用しています。Deno は、JavaScript/TypeScript のランタイムです。Node.js の作者である Ryan Dahl が開発を始めました。主な特徴としては、Node.js と比べてデフォルトでセキュアである事と、標準で TypeScript に対応している点だと思います。
https://deno.land/

日本語の情報としましては、以下の Zenn Book がお薦めです。
https://zenn.dev/uki00a/books/effective-deno

Fresh

https://fresh.deno.dev/
Fresh は Deno Web アプリのためのフレームワークです。denoland の organization で開発されています。Preact を利用しており、Islands Arhitecture というパターンを使っています。
開発起動中に routes コードを自動生成し、dynamic import 不要にしているようです。起動時にすべての依存を解決するのでこの辺の仕組みは良いなーと思いました。

理解してないこと

island と component の違いを理解していません(誰か教えてください。。)。

Deno Deploy

https://deno.com/deploy

実行環境は Heroku から Deno Deploy に変更しました。Heroku では、60秒以内に起動しないとタイムアウトになるので回避策を講じていましたが、それを気にする必要もなくなりました👍(Deploy も速くなった)。

Supabase

https://supabase.com/
データストアとして Supabase の PostgreSQL を利用しています。
Heroku PostgreSQL のフリープランを使っていた頃は、証明書の取得ができなかったために、deno の実行時に --unsafely-ignore-certificate-errors オプションを付け、証明書のエラーを無視していました。Supbase は、フリープランでも証明書の取得し利用できるため、この問題は発生しません👍。

以下の PostgreSQL ドライバを利用しています。
https://deno-postgres.com/

PostgreSQL の証明書は、ファイルでは管理せず、以下のように環境変数から取得しコネクションプールを生成するようにしています。Deno Deploy の場合は、管理画面から環境変数に追加しています。

const pool = new Pool(
  {
    tls: {
      enforce: false,
      caCertificates: [
        `-----BEGIN CERTIFICATE-----\n${
          Deno.env.get("MDSNS_DATABASE_CA_CERTIFICATE")
        }\n-----END CERTIFICATE-----`,
      ],
    },
  },
  5,
  true,
);

証明書ファイルは、複数行になっていますが改行コードを潰し、1行にして設定すれば OK です。

全文検索

「最近 Supabase で日本語の全文検索が簡単になった」という話しがあったので日本語での検索機能も実装できました👍。
以下のブログ、ドキュメントを読んで実装できました。
https://supabase.com/blog/launch-week-6-community-day#pgroonga-multilingual-search-extension
https://pgroonga.github.io/tutorial/
Supabase 素晴らしい。

Tailwind ?

Fresh は、twind(Tailwind)をサポートしており、最初 Bootstrap で書いていたコードを twind に書き換えようかと思ったのですが、時間がかかりそうと判断し、途中で挫折しました。。

DOMPurify

https://github.com/cure53/DOMPurify
マークダウンから HTML に変換するモジュール marked からサニタイズの機能が消えてしまったため、DOMPurify を利用しました。最初、サーバ、クライアント両方で動作させようとしたのですが、サーバサイドでの実行が上手くいかず、マークダウンの変換はすべてクライアントサイドで動作させるようにしています。。

おわりに

Deno, Fresh, Deno Deploy, Supabase とっても良いと思います!
色々作れそうですね。

以上です。

Discussion