BookmarkletをWebpackで作る

それって意味有るの?

ある。正直手でBookmarkletを書くのはしんどい。 規模が大きくなればなおさら。 とは言えFirefoxを基準に26kbあたりまで書くとなるとしんどい。

qiita.com

手書きBookmarkletがしんどい理由
  • ファイル分割してClassごと別にして処理を使いまわしたい
  • 改行制御を考えたくない
    • IED(VScode)でESLintやPrettierの恩恵を受けたい。勝手に改行される。
    • Git、Githubで差分管理をしたい。ここを1行だと差分管理は難しい。
実際にできるのか?

できる。 消す処理を

  • Webpackでビルドして
  • Terserでコメントなし、minifiyでいける。 ただこの場合、外部ライブラリ利用のライセンス違反の誹りは免れない。
  • コメント付きの場合でも、URLの//を除いてコメント消す処理を入れて改行を半角スペースにするなどでなんとかできる。
テクニック

ただ、それでものほほんと書くとすぐ23kbを越えてしまう。 なので、くだらないが努力が必要である。

  • TerserのMinifyを見ていくと最適化されない部分が有る
  • その最適化されない部分を手でなんとかする。
  • 対象はリテラルとプロパティ名(メソッド名)である
  • わかりにくさ覚悟でプロパティ名は1文字〜に短縮していく。
  • 出来るだけ機能限定、自作ライブラリを基本とし既存ライブラリは極力手を出さない。
  • cssは諦めろん
  • 試していないが、function()はうざいので()=>{}への書き換えはできると思われる。
  • console.log?やめろ!
  • documentとかWindowは1文字変数に入れておけ
機能拡張

結局Chrome以外はMB級のVue.js+Veutifyなどと言うライブラリをブックマークレットは使えない。 また一部にはWebpackに入れることが出来ない古いライブラリ、zlibjsやらライセンス表記違反の可能性も有るので やはりiframe等で本体を召喚してそちらで処理をするのが良いように思われる。

ブックマークレットの構成としては次のようになる

  • fetch:ドメイン内にリクエス
  • iframe:本体ページを召喚
  • postMessage:iframe側と通信
  • ※CORSで取得したデータをjsとして実行した瞬間ブラウザから蹴られるので注意。
限界点

次の対策を取られたセキュリティに意識の高いページではそもそもブックマークレットは使えない

  • CSP(Content Security Policy)がhttpヘッダーに設定されており、使えるスクリプトが限定されている

ただ、同じドメインにCSPを設定しないXMLJSONAPIエラーパスが有れば回避は不可能ではない

  • エラーページでブックマークレットを発動
  • iframeで目的のページを開く
  • ifarmeをjsで操作
  • 本体はもう一個別のiframeを表示してエラーページ上でバイパスする

等である。もちろんクリックジャッキング対策でiframe呼び出しを禁止されて無ければだが。

以上

可能性はある。 しかし厳しいサイズ制限が有るので単体では完結しない。iframe必須。 iframeがないとかなり厳しい。 幸いなのが、IE対応サイトのかなりの部分はCSPの設定もなければiframeも使える。

さてはてコレデイイノ感は拭えないけどね。