【TypeScript】Qiitaのストックにコメントを付けられるChrome拡張を作ってみた

Qiita Stock Commenter TypeScript

Udemyで購入したTypeScriptの講座が一通り終了しました。

JavaScriptのフロント側操作復習とTypeScriptの練習のため、
Qiitaのストック記事にコメントを付けられるGoogleChrome拡張を作ってみました。

ツール説明

Qiita Stock Commenter

Stockページのタイトル下に最長60文字のメモ書きが可能です。
カーソルが離れたタイミングで保存されるので上書き等に注意して下さい。

sena-v/type_test
Contribute to sena-v/type_test development by creating an account on GitHub.

使用技術,ツール
TypeScript / Webpack / localStorage

前提

・JavaScriptは業務システムのValidationとか、要素取得・文字挿入などDOM操作を少々
・文法は一通り両方とも学んだけど、なにがわかって何が分からないか分からない
・JSフレームワークの学習をTSでやろうとしてるけど先に簡単な物をなにか挟みたい
・記事ストックが溜まってきたけど、ストック理由の切り分けができていない
簡単なchrome拡張なら1hでできるみたいな記事読んだし、1日で作れるラインを目指す

じゃあ練習にもなるしストックにコメント付けられれば良くない?みたいな感じで作りました。

実装

let Target = document.querySelectorAll('article');

上記のquerySelectorで取ってきたNodeListOfを繰り返し処理します。

for (TargetDiv of Target) {

  TargetChildDiv = TargetDiv.children[1].children[2]
  ArticleNode = TargetDiv.outerHTML;

  UrlStartPlace = ArticleNode.indexOf('data-item-url') + 16;
  UrlEndPlace = ArticleNode.indexOf('data-secret') - 2;

  ArticleUrl = ArticleNode.slice(UrlStartPlace, UrlEndPlace)

  // 挿入するdiv要素を生成
  let newEle = document.createElement('input');
  newEle.setAttribute('Id', ArticleUrl) // divタグのIDが記事番号になる
  newEle.setAttribute('type', 'text')
  newEle.setAttribute('maxlength', '70')
  newEle.setAttribute('style', 'height:2em;width:610px;margin-bottom:3px;')
  newEle.addEventListener("blur", function () {
    // 記事Id(url)をKey、inputされた文字をvalueとしてLocalStorageに投げる
    let Id: string = this.id
    let InputData = this.value;
    localStorage.setItem(Id, InputData);
  });

  // R処理にlocalStorageを使用する
  MemoData = localStorage.getItem(ArticleUrl)!;

  // 取得できたメモデータをセットしinputを挿入 
  if (MemoData) newEle.setAttribute('value', MemoData);
  TargetChildDiv.parentNode!.insertBefore(newEle, TargetChildDiv);
}

要素単体の処理は簡単ですが以下の流れになっています。
①取得記事(HTMLElement)からUrlを抜き出し、user名-記事Urlをidとしてinput要素を作成
②input要素のonblurにlocalStorageへの保存処理を埋め込む( key: id, value: inputのvalue )
③記事keyでlocalStorageからgetし、存在した場合メモデータをセットし要素を指定位置へ挿入

結局gitHubのリリースの書き方を調べたり、chrome.storage(後述)で詰まったり、
記事を合間に書いたりして実質10時間くらいの作業になりました。

困ったこと・つまった所

Object is possibly ‘null’がめっちゃ出た

querySelector等でDOM要素を取得する処理について、実行するまで要素が存在するか
わからないことからトランスパイルを実行して初めてエラーが見つかりました
(Lintツール変更したら先に出るのかな?)

今回は確実に存在するidをquerySelectorで取得する新規Elementを挿入する処理をする関係で
対応する要素が必ず存在するため、Non-null assertion operatorを使うことで解決しました。

参考:TypescriptでgetElementByIdを使ったら「Object is possibly ‘null’」のエラーが出た時

chrome.storageがちゃんと動かない(未解決)

chromeの機能でKey-value型を内部に保存する方法があり(chrome.storage)、設定次第でchromeアカウント内のデータ共有が可能なため導入したかったのですが実行時エラーを吐かず結果が返ってきませんでした。

参考記事を読んだところsync設定の利用制限が厳しい※1であったり、LevelDBで実装されているので別途学習が必要な気がしたこと、そもそもプログラミングするPCでメモが保存できて
あとで見れれば最低限いいよね
※2 という理由から、localStorageを選択しました。

※1:制限の範囲は今回の用途では問題ないレベルでしたが、今後PC間でデータを共有する
ツールを作る際に汎用性が高いFirebase等の処理を学習した方がタイムパフォーマンスが
良いと思い採用をやめました。

※2:データ量が少ないと思うので最悪共有はInport/Outportできるようにするかも?

参考:ブラウザにデータを保存するlocalStorage(ローカルストレージ)の使い方

欲しい要素を探すためにObjectの型を考えながら実装する必要がある

検索してきたJS処理をTSに変換する場合、型とプロパティをより意識して実装する必要が
あります。型の恩恵でJSと違いブラウザで実行する前にエラーに気付くことができたので
そこは良かったのですが、prototypeにchrome.storageデバッグ時にデータが入っているのか
いないのかを見る事に時間がかかりました。

参考:
ECMAScrip、TypeScript には class 定義 があるが、プロトタイプチェーンはおさえておこう

今回TypeScriptを使用し複雑すぎないDOM操作をすることで、型を(チェックしてくれるので)
意識しすぎずに要素のprototypeを意識できたので課題ができて良かったかなと思っています。

また型を明示的に書いていないのでイマイチTypeScriptの恩恵が受けられているか分からない
ことと、よりTypeScriptの強みを生かした書き方がも今後必要かなと思いました。

作ってみて・今後やりたいこと

JavaScriptの処理をTypeScriptで直接使えない時に困る、けどやっぱり型が便利

多くのDOM操作についてはJSでの情報がほとんどなので、querySelectorで取った要素が
単数だと思っていたら複数で、使おうと思っていた処理がindex指定しないと使えなかったとか、thisが想定していた結果と違うとか取ってきた情報をそのまま使えない部分がありました。
ただその際もやはりTypeScriptは便利で、どこがなんの型でダメと具体的に教えてくれる分、
スムーズに開発することができました。

以前Ecpilseでフロントの開発をした際は実行してみないと間違っている箇所がわからず苦労した経験があるので実行前に色々判断してくれる、オブジェクトの型を意識しながら開発できるTypeScriptは有利に感じました。

TypeScriptの前にJavaScriptをもう少し滞りなく書けるようにしたい

良くも悪くも型システム+VScodeのlint、補完機能が優秀なのであまりJS自体を理解していなくてもそれなりに進んでしまう所が多く、JSの記法を調べたりする時間が比較的長かったです。

おわりに

今後TypeScriptをやろうとする場合、流れを考えるとJavaScriptのチームに参画した上で
同意の下で導入していくケースになると思うので、サーバーサイド知識も使えるNode.JS周りを
勉強しながら実用的はJavaScriptのコーディングをしていきたいと思います。

参考記事
外部に公開しないミニマムなchrome拡張機能を作るのは1時間も使わずにできる
TypeScriptで作るイマドキChrome拡張機能開発入門
図で理解するJavaScriptのプロトタイプチェーン

コメント

タイトルとURLをコピーしました