Next.jsでEvernoteの代替アプリを自作してみた

[UdonTech Advent Calendar 2023](https://qiita.com/advent-calendar/2023/udontech)の25日目です。

- 2022-11-16 [Evernote’s Next Move: Joining the Bending Spoons Suite of Apps](https://evernote.com/blog/evernote-next-move-joining-bending-spoons)
- 2023-04-28 [Evernote の価格プラン改定と今後の機能強化に関するお知らせ](https://evernote.com/ja-jp/blog/evernote-pricing-upcoming-features-update)
- 2023-07-08 [Moving the Evernote center of operations to Europe](https://evernote.com/blog/moving-the-evernote-center-of-operations-to-europe)
- 2023-11-29 [Evernote Free accounts will have fifty notes and one notebook](https://evernote.com/blog/evernote-free-note-limits)

というわけで今年5月からNext.jsの勉強も兼ねてEvernoteの代替アプリを自作していました。本記事で開発過程や中身を簡単に紹介します。

完全に個人用のアプリなのでサービス公開とかはありませんが、ソースは以下にあります。ドキュメントはないですが()、頑張れば誰でもセットアップできるかもです。

https://github.com/k-mitani/note2

画面はこんな感じです。

![20231225_183555_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/32fa5816-894e-ce5b-6c82-bcc5bdc8dda8.png)

# 開発過程

## 5月 Next.jsの勉強

上記のEvernote値上げ告知を見てEvernoteから別のアプリに移行する決心をしました。ずっと前から移行先を探していたのですが、いまいちしっくりくるアプリがないので、Web系技術の勉強も兼ねて自作することにしました。

Next.jsが流行っているようなので、Next.jsで自作することにしました。まずはNext.jsの勉強を行いました。

###   主にやったこと
-  Next.jsの公式チュートリアルを一通りやる
-  日本語の解説記事をたくさん読む
    - はてなブックマークで、タイトルにNext.jsとついていて、3 users以上ブックマークがついている一年以内の記事のなかで、気になった記事を片っ端から読む！
    - 特に良かった記事 → https://eh-career.com/engineerhub/entry/2023/04/18/093000
        - 簡単なノートアプリ開発を通してNext.jsの基本を身につけるという、やりたいことにドンピシャな内容でとても参考になりました
- 本を読む
    - [『TypeScriptとReact/Next.jsでつくる実践Webアプリケーション開発』](https://gihyo.jp/book/2022/978-4-297-12916-3)
    - [『WEB+DB PRESS Vol.133』- Tailwind CSS実践入門](https://gihyo.jp/magazine/wdpress/archive/2023/vol133)

まずはチュートリアルや解説記事をたくさん読んで、Next.jsのお作法や一緒によく使われるライブラリーなどを把握していきました。それだけだとまだNext.jsを使いこなすのが難しいなと思ったので以下の技術書も読みました。

『TypeScriptとReact/Next.jsでつくる実践Webアプリケーション開発』・・・Next.jsの入門書です。純粋な技術解説だけでなく、Webフロントエンド技術の変遷の歴史なども分かりやすくまとまっていてとても良かったです。

『WEB+DB PRESS Vol.133』- Tailwind CSS実践入門・・・Next.jsがデフォルトでおすすめしてくるTailwindの解説記事です。この記事を読んだおかげでTailwindの気持ちが大分わかるようになりました。

どちらの技術書も当たりでした。この2冊を読んだおかげで大分Next.js・Tailwindの書き方が分かってきました。

↓この頃のつぶやき（Tailwind CSS実践入門を読む前）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/cb754d29-60b5-da2b-634b-6efed32a43a7.png)


## 6月 アプリ開発

実際にアプリを作っていきました。

### Evernoteのデータ変換、表示

まずはEvernoteからデータをエクスポートして自作アプリから扱いやすいデータ形式に変換しました。

EvernoteのエクスポートデータはenexというXML形式のデータです。enexの中身を調べると、ノートの本文はCDATAセクションに埋め込まれたただのHTMLドキュメントでした。それにプラスアルファでノートのタグや更新日時の要素がついてる感じでした。なので、enexからノートの本文を抜き出して適当なHTMLページのdiv要素に挿入したら、Evernoteと同じ見た目でそのまま表示できました。

とりあえずenexファイルをJavaScriptで扱いやすいようにJSONに変換して、そのJSONデータを表示する処理を作っていきました。

変換処理は適当にC# (LINQPad) で作りました。所詮ワンオフの作業なので適当です💪（TODO あとでデータ変換処理のコードを貼る）

↓その頃のつぶやき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/f96a8d49-b540-f7e4-0b96-8b7fe7878164.png)

### ノートデータのDBへの格納、フォルダー操作実装

JSONデータの表示がある程度出来てきたので、Prismaを使ってDBに格納して取り出す方式に作り変えていきました。

↓その頃のつぶやき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/7a1be0cd-d841-c19e-e934-f135ba7225b8.png)

### ノート新規作成機能追加、編集機能追加

ノート新規作成・編集ができるようにしていきました。

編集機能は、良さげなリッチテキストエディター系のライブラリが色々あって迷いましたが、とりあえず一番シンプルな[react-contenteditable](https://www.npmjs.com/package/react-contenteditable)を使うことにしました。何か気の利いた編集機能を追加したかったら昔ながらの `execCommand()` (非推奨) を自前で呼び出す感じで、とても安心感があります😊

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/fa7acccd-bd4c-93e9-d4c3-4f4af765d81f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/83f74c64-4acd-5002-31ab-89b5c0ebcbfd.png)

## 7月～

6月である程度基本的な機能は作れたので、7月以降は実際にノートアプリを使いつつブラッシュアップやモバイル対応を行っていきました。

### （余談）UdonTech LT大会で発表

7月15日の[UdonTechのLT大会](https://udontech.connpass.com/event/286292/)で発表してきました。内容は本記事と似たような話です。

https://docs.google.com/presentation/d/1mXQx3KXcAaIkeA7NG46fuRrxyegrR2PEkVR53DlqYEA/edit?usp=sharing

### PWA対応

スマホのホーム画面やWindowsのタスクバーにピン止めできたら便利なのでPWA対応しました。

ついでにWeb Share Target API（スマホの共有メニューにアプリを表示できるようにするAPI）に対応したりもしました。[（当該コミット）](https://github.com/k-mitani/note2/commit/0fba60bb8f371b74953d5e3b05df1e59f9abce67)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/269906e4-70f4-acbf-6650-ee8fc049e7be.png)

### 色々機能追加

#### URLのカード化

Notionにあって便利だった、URLを貼り付けたらリンク先の情報をカード化して表示する機能をつけました。使用したライブラリ → https://github.com/jacktuck/unfurl

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/702c77c8-a90e-2e68-8806-98586e8c0998.png)

#### ダークテーマ

ダークテーマを実装しました。Tailwind便利だと思いました。（なお保守性は不明）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952672/4224fb6c-c8bb-c920-6f7a-54525ed19cde.png)

#### WYSIWYG

GoogleドキュメントっぽいWYSIWYG編集ショートカットを追加しました。 `execCommand()` は偉大です。

#### 貼り付けた画像のS3への保存

画像を貼り付けるとData URIスキームでノートに埋め込まれてノートサイズが肥大化していたので、クリップボードデータを読み取って画像をS3にアップロードする形に変更しました。


# 終わりに

今まで作った主な機能は以上です。

まだまだ欲しい機能はたくさんありますが、現状でも便利に使えています。Evernote時代よりサクサク動くようになっただけでも満足ですし、もうこれ以上アプリが望まない方向に改悪されて落胆することがなくなるのも良い感じです。

ReactやNext.jsやTypeScriptなどモダンなWeb開発の勉強もできて良かったです！（ソースコードは大分🍝化しつつありますが...）

以上です。アドベントカレンダーお疲れ様でした！