<div contentEditable /> の闇

最近 WYSIWYG エディタに憧れて ContentEditable をいじって独自エディタを個人開発しています。 その際に色々苦労した点について備忘録としてブログにしたいと思います。

このコードの handleClick でしていること分かりますか?

import { MouseEvent, useState } from 'react';

export function Editor(): JSX.Element {
  const [content, setContent] = useState<string>('');
  console.log('content:', content);

  const handleClick = (e: MouseEvent<HTMLDivElement>) => {
    if (!e.currentTarget.textContent) {
      e.currentTarget.innerHTML = '<p><br></p>';
    }
  };

  const handleInput = (event: React.FormEvent<HTMLDivElement>) => {
    const { textContent, innerHTML } = event.currentTarget;

    if (!textContent) {
      event.currentTarget.innerHTML = '';
    }
    setContent(innerHTML || '');
  };

  return <div contentEditable onClick={handleClick} onInput={handleInput} />;
}

textContent を見て何も入力されていない場合のみ、innerHTML に"


" のタグを追加しているいる処理ですがきっとこの処理を見た人はなんでこんなことするの?って思うかと思います。

AWS App Runner : 基本情報

AWS App Runner ってどんなサービス?

コンテナ化されたウェブアプリケーションAPI を開発者が簡単かつ迅速にデプロイできるフルマネージド型サービスです。

FYI: マネージド型のコンテナアプリケーションサービス - AWS App Runner - Amazon Web Services

もっと簡単に噛み砕いて説明すると、コンテナに関する知識がなくても AWS におまかせで WEB アプリケーションを公開できる便利なコンテナのフルマネージド型サービスです。

2022年の振り返り

週末起業の失敗と転職

今年は色々なことがあっていい意味で充実した 1 年ではなかったが、たくさんのことを学んだ1年だった。

週末起業の失敗

中学時代のシニアの後輩と部活動内のコミュニケーションを変えたいと思い、"ClubStack" というタイムラインとカレンダーの機能を搭載したアプリを 2021 年の 9 月にローンチし、2022 年 11 月 30 日まで運営した。

結果としては、サービスを PMF をさせることができずサービスをクローズすることになったが 0 から立ち上げたサービスを 約 600 人のユーザーに利用していただけたことはとても勉強になったと同時に、とても悔しい思いもした。それとサービス終了することをご利用いただいているチームにお伝えしたときにお金を払うから運営し続けて欲しいと言われた時は気持ちが張り裂けそうになった。

また、サービス終了することになって一時期はもう起業はいいやと思ったが、ここ最近になってまた何か生み出したい気持ちが湧いてきたので周りをもっと巻き込める人になって 2 ~ 3 年後に再チャレンジをしたい。

転職

まさか自分が外資クラウドベンダーで働くなんて、リクルーターから 1 通のメッセージを送られてくるまで考えたこともなかった。

学生時代に 2 ~ 3 社経験したのちに起業しようと、大学卒業後はカートシステムを提供する上場企業でエンジニアでキャリアをスタートした。それから転職し、2022 年 8 月 31 日まで勤めていた 2 社目ではフロントエンドエンジニアとして働いた。

大学卒業してから 4 年経ち、前職の会社がスタートアップだったこともあり前職が上場するタイミングあたりで起業したいなって考えていた。しかし、前職の会社の上場時期が不透明になり、運営していたサービスで独立を考えていたがいろいろ難しくなりどうしようと思ったタイミングで LinkedIN でリクルーターから 1 通のメッセージが来た。

最初にメッセージをいただいたときには「送る人間違っているのでは?」と思ったが、せっかくの機会だから話だけ聞いてみようとメッセージに返信したらすぐに返信がきて、電話で 10 分ほど話したら選考を受けることになった。

選考の詳細については話せないが、最終のループ面接でかなりメンタル削られた。志望動機を一切聞かれず、淡々と自分の話したエピソードを深掘りされるあの面接はもう 1 回受けたら受かる気がしない。

そして、内心「絶対受からないでしょ?」って思って選考を受けた会社で今働いている。具体的に何しているとか、転職してから働いてみて思うことはまだ数ヶ月しか経っていないので来年の 1 年の振り返ってみたい。

2022 年を振り返ってみて

2022 年は、何かを達成はできなかったが、いろいろ人に出会い、悔しいことばかりだがいろいろな経験をした 1 年だった。来年は何かを成し遂げるとかを目標とするより、自分自身を成長させる 1 年にしたい。とりあえず、現職に転職してから自分の英語力の無さと基礎的な技術力がまだまだないなと思ったので、来年は英語とエンジニアとして必要な知識を勉強したい。

2023 年中に TOEIC 900 点以上取る。(今まで受けたこともない)

AWS App Runner で Next.js をデプロイしてみた

対象者

AWS の App Runner で Next.js をデプロイする方法を知りたい方

方法

AWS : App Runner :: Region : ap-northeast-1

  1. AWS : App Runner :: Region : ap-northeast-1」にアクセス(リージョンはお好きなリージョンを使ってください)
  2. 「サービス作成」をクリック
  3. 「ソースおよびデプロイ」から各種項目を入力(詳細は下記を参考に)
  4. デプロイ開始すると 10 分ほどでデプロイ完了します。

ソースおよびデプロイ

ソース

リポジトリタイプ

ECR のコンテナのイメージをホストしてもいいですが、「ソースコードリポジトリ」の方がECRへのホスティング費用を抑えることができるので「ソースコードリポジトリ」を利用することをおすすめします。(Next.js でコンテナ化するメリットがないため)

GitHub に接続

よしなに GitHub の接続設定をして、該当のリポジトリを選択してください。

デプロイ設定

デプロイトリガー

  • 手動 => 選択
  • 自動

今回は手動としているが、デプロイフローに合わせて選択してください。

構築を設定

構築設定

設定ファイル

  • ここですべての設定を構成する => 選択
  • 設定ファイルを使用

デプロイフローに合わせて好きな方を選択してください。

ランタイム

  • Corretto 8
  • Corretto 11
  • Nodejs 12
  • Nodejs 14
  • Nodejs 16
  • Python 3

お使いの node のバージョンを選択してください。

構築コマンド

npm install

開始コマンド

npm run exec

ポート

デフォルトの「8080」ポートを利用します。(お好みで好きなポートに変更も可能)

サービスを設定

サービス設定

サービス名

お好きなサービス名をつけてください。

**仮想 CPU とメモリ

今回は、「1 vCPU」、「2 GB」と必要最小限のミニマムの設定にしました。

適宜、運用状況に合わせて変更してください。

環境変数 - オプション

環境変数を設定することできます。

運用しているサービスに合わせて環境変数を設定してください。

Auto Scaling

「デプロイしてみた」なので、何も設定していません。

ヘルスチェック

「デプロイしてみた」なので、何も設定していません。

セキュリティ

「デプロイしてみた」なので、何も設定していません。

ネットワーキング

「デプロイしてみた」なので、何も設定していません。

可観測性

「デプロイしてみた」なので、何も設定していません。

タグ

「デプロイしてみた」なので、何も設定していません。


上記まで設定完了したら「作成とデプロイ」をクリックするとデプロイ開始します。

iTerm2のウィンドウサイズを保持する方法

対象者

iTerm2でタブを閉じるときに縦にウィンドウサイズが縮小されるのを防ぐ方法

前提

iTerm2のデフォルトの設定では、シングルタブの時はタブバーが表示されない。

タブを作成して複数タブの時に初めて、タブバーが表示される。

※ シングルタブの時でもタブバーを設定で表示することもできる。

シングルタブと複数タブでタブバーの表示・非表示に違いが発生するため、マルチタブからシングルタブにした時に縦にウィンドウサイズが縮小される。

モチベーション

人によっては気にされない人もいるが、個人的には気になるので以下の方法でウィンドウサイズを固定できるようにした。

設定手順

  1. 「Preferences⇒Appearance⇒Tabs」
  2. 「Preserve window size when tab bar shows or hides」にチェックを入れる

上記の2手順で設定することができる。

huskyを追加してpre-commitでESLintを走らせる方法

対象者

node.jsのプロジェクトでpre-commitを走らせて、npm scriptを実行してESLintやJestを走らせたい方

方法

  1. huskyのライブラリーをインストール
npm install husky@latest

"husky": "^8.0.1"の最新バージョンがインストールされるはず(2022.7.21現在)

  1. git hooksを有効化

npmの場合

npx husky install

yarnの場合

yarn husky install
  1. pre-commitを作成
# exampl
npx husky add .husky/pre-commit "npm 【your npm script(ex. eslint)】"
# ex1.
npx husky add .husky/pre-commit "npm run eslint"

GitHub Actions : SSHの接続方法

対象者

GitActionsでSSH接続する必要がある人。

ex. 例えば、node.jsのpackage.json内でprivate repositoryからnpm install or yarn installしたい時。

SSH Keyを作成

ssh-keygen -t rsa -f git_actions

秘密鍵の設定

pbcopy < git_actions

上記のコマンドで秘密鍵クリップボードにコピーする

https://github.com/your-name/sample-app/settings/secrets/actions

次に上記のURLから【Actions secrets】でPRIVATE_KEYを設定する

設定方法は、上記のスクショを参考に

公開鍵の設定

pbcopy < git_action.pub

上記のコマンドで公開鍵をクリップボードにコピーする

https://github.com/settings/keys

次に上記のURLから公開鍵を登録

GitActionsの設定

今回はcommitをpushした時に、CIを走らせるgit actionを作成

name: sample

on: pull_request

jobs:
  sample:
    runs-on: ubuntu-latest
    timeout-minutes: 30

    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: 14.x
          registry-url: 'https://npm.pkg.github.com'

      - name: Run setup ssh
        env:
          PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
        run: |
          mkdir -p ~/.ssh
          echo "$PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_rsa
          chmod 700 ~/.ssh/id_rsa
          eval $(ssh-agent -s)
          ssh-add ~/.ssh/id_rsa
          ssh-keyscan -H github.com >> ~/.ssh/known_hosts

      - name: Run install
        run: yarn install

終わりに

上記まで設定が完了したら実際にpushしてみてgit actionyarn installが問題なく出来ることを確認してください。(出来ていない場合は何か設定ミスが発生しているはず)