mizdra's blog

ぽよぐらみんぐ

Chrome拡張機能でコールバック地獄を解決する

Chrome拡張機能の非同期APIはコールバックにより実装されています. 例えば, 拡張機能ごとに用意されるストレージからデータを取得する場合, ストレージへのアクセス中にJavaScriptの処理が中断されるのを防ぐため, 非同期APIが用意されています.

// background.js
chrome.storage.local.get(['admin'], (result1) => {
  chrome.storage.local.get([`user/${result1.admin}/name`], (result2) => {
    console.log(result2)
  })
})

このコールバックによる非同期APIはJavaScriptにおいては一般的な非同期APIの実装手法ですが, 「コールバック地獄」という問題を引き起こします. これを解決する手法としてES2015で追加されたPromiseとジェネレータ, もしくはES2017で追加されたasync/awaitを利用する手法が知られています.

numb86-tech.hatenablog.com

numb86-tech.hatenablog.com

susisu.hatenablog.com

しかしChrome拡張機能の非同期APIはコールバックにより実装されているため, Chrome拡張機能の中では直接的にはPromiseasync/awaitを利用することが出来ません. そのため, 手動で非同期APIをPromiseでWrapするか, 以下のようなWrapperライブラリを利用する必要があります.

この記事ではmozilla/webextension-polyfillを使ってコールバック地獄を解決する方法を紹介します.

mozilla/webextension-polyfillを使ってコールバック地獄を解決する

ブラウザ間で統一的なAPIで拡張機能を作成できるよう策定されたWeb Extension APIというものがあり, 現時点でMozilla FirefoxとMicrosoft Edgeでサポートされています. mozilla/webextension-polyfillはこのWeb Extension APIのChrome向けのPolyfillとなっています. Web Extension APIの非同期APIは全てPromiseで提供されているため, Chrome拡張機能でコールバック地獄を解決する方法として用いることができます.

mozilla/webextension-polyfillnpm.comからもインストールできますが, モジュールバンドラなどを挟む必要があるため, 少々手間です. これに変わるより手軽なものとして, unpkg.comから直接ライブラリをダウンロードし, manifest.jsonbackground.scriptsなどから読み込む方法があります.

$ cd extension-project
$ wget https://unpkg.com/webextension-polyfill/dist/browser-polyfill.min.js
// manifest.json
{
  // ...

  "background": {
    "scripts": [
      "browser-polyfill.min.js",
      "background.js"
    ]
  },

  "content_scripts": [{
    // ...
    "js": [
      "browser-polyfill.min.js",
      "content.js"
    ]
  }]
}

このようにPolyfillを読み込むことでbackground.jsなどからbrowserという名前空間からWeb Extension APIにアクセスできます.

// background.js
browser.storage.local.get(['admin'])
  .then((result) => {
    return browser.storage.local.get([`user/${result.admin}/name`])
  })
  .then((result) => {
    console.log(result)
  })

非同期APIはPromiseを返すので, 次のようにasync/awaitを利用したコードにも書き換えることもできます.

// background.js
(async () => {
  const result1 = await browser.storage.local.get(['admin'])
  const result2 = await browser.storage.local.get([`user/${result1.admin}/name`])
  console.log(result2)
})()

以上, Chrome拡張機能でコールバック地獄を回避するTIPSでした.

#NowPlaying for Google Play Music 拡張機能の v1.0.0 をリリースしました

はじめに

先日公開した Google Play Music 向けの #NowPlaying 拡張機能 がアップデートして v1.0.0 になりました 🎉🎉🎉

新機能

  • Firefox のサポート
  • ユーザカスタム設定をサポート

Firefox のサポート

要望のあったFirefoxのサポートを実装しました. Chromeと全く同じように曲の共有が行えるようになります. 以下のリンクからFirefoxにインストールできます.

これはFirefox 48にて採用された WebExtensions API を利用すること実現されました.

ユーザカスタム設定をサポート

SNSメッセージのテンプレートや付加するハッシュタグをユーザがカスタマイズできるようになりました. 設定のカスタマイズは拡張機能のオプションから行うことができます.

f:id:mizdra:20180525155527p:plain

テンプレート内に埋め込める変数として, 次の3つをサポートしています.

  • ${title}: 曲のタイトル
  • ${artist}: 曲のアーティスト名
  • ${album}: 曲のアルバム名

おわりに

より使いやすくなった #NowPlaying for Google Play Music を是非お試しください!

Google Play Music 向けの #NowPlaying 拡張機能を公開しました

はじめに

Google Play Music 向けの #NowPlaying 拡張機能, ありそうで無かったので作りました.

chrome.google.com

上記の拡張機能をインストールすると, 右下に曲のシェアボタンが表示されるようになります.

f:id:mizdra:20180523010803p:plainf:id:mizdra:20180523010800p:plain
右下の共有ボタンを押すと共有するSNSメッセージを編集する画面に遷移する.

サポートされるSNS

サポートしているSNSTwitterのみです. 現状他のSNSに対応するつもりは無いので, もし他のSNSにも共有したい人がいれば以下のGitHubリポジトリをForkするなりPullRequest送るなりしてもらえればと思います.

github.com

その他

拡張機能, シュッと作れると思っていたらChromeウェブストアで利用するプロモーション用の画像を用意する必要があったり, ロゴのデザインが指定されていたり, デベロッパー登録手数料として$5払ったりする必要があってちょっと面倒だった… コード書くのは大分速くなった気がするので, そろそろデザインもシュッとできるようになりたいですね.

おわりに

インストール!!! 今すぐ!!! シェアボタン連打!!!

WebAssembly 開発環境構築の本を公開しました

はじめに

Rust を用いて WebAssembly の開発環境を構築する手法を紹介する電子書籍を執筆・公開しました. WebAssembly へのコンパイルが可能な言語である Rust を用いて, WebAssembly の開発環境のテンプレートを作成する内容となっています.

wasm-dev-book.netlify.com

本のタイトルからは一見すると C/C++ を用いた開発環境の構築も扱うように受け取れますが, 本書では Rust のみしか扱っておりません. ご注意下さい.

書籍の執筆動機

著者が春休み中に WebAssembly を用いて Web アプリケーションを作成する機会があり, 本書はそこで得た知見を纏めたものとなっています *1. 元々大学のサークルで発行した部誌に同じテーマで記事を書いており, 本書ではそれを Web 向けに編集・加筆した内容から構成されています.

ここ最近 WebAssembly が急速に注目されており, 既に C / C++ / Rust などで利用することができるほか, 記事執筆時点でGolang でも WebAssembly のサポートが実装作業中となっています. また, 2017 年になって主要なブラウザ全てで WebAssembly がサポートされ, 2018 年に入って主要なモジュールバンドラで WebAssembly がサポートされるようになりました.

こうした需要の高まりに合わせて本書を公開することで, WebAssembly に興味を持っている人が WebAssembly を触り始めるきっかけになればと考えています.

書籍の目的

本書は Rust を用いて, WebAssembly の開発環境のテンプレートを作成する手法を学ぶことを目的としています. 本書の目的 の節には次のように書かれています.

  • Rust を用いた WebAssembly の開発環境を構築する手法を知ること
  • モジュールバンドラと連携する方法を知ること
  • TypeScript と連携する方法を知ること
  • WebAssembly を利用していて陥りやすい罠を知ること
  • WebAssembly に関する情報を調べる方法を身につけること

反対に, 次のような内容は本書では扱いません.

  • WebAssembly / Rust / JavaScript の文法や機能の解説が目的ではない
  • JavaScript のエコシステムの解説が目的ではない
  • C / C++ を用いた WebAssembly の開発環境を構築する手法の解説は目的ではない
  • WebAssembly や JavaScript の仕様変更の追従が目的ではない

本書の「Rust を用いた WebAssembly の開発環境を構築する手法を知る」というテーマに沿った内容を扱うため, テーマから外れた内容は扱わないことにしています. 読むにあたって足りない知識は本書の はじめに の節に書かれているサイトを参考に各自補完していって下さい.

また, WebAssembly は Web の最先端の技術の 1 つであり, 仕様や関連技術の変化が非常に活発です. したがって仕様変更など WebAssembly 関連の最新情報を本書に反映することは困難であり, これらの変更の追従は本書では行いません.

書籍の目次

本書の内容をざっと確認できるように目次を貼っておきます.

  • WebAssembly 開発環境構築の本
    • 本書の目的
    • 本書でやらないこと
    • 本書の対象読者
    • 本書の読み方
  • 著者への寄付
    • 寄付先一覧
    • 著者の情報
  • はじめに
    • 本文章を読むにあたって
    • 開発環境について
  • WebAssembly 入門
    • WebAssembly を試す
    • WebAssembly から JavaScript の関数を呼び出す
    • Rust のサードパーティ製ライブラリの利用
    • 本節のまとめ
    • 参考文献
  • Parcel の利用
    • Parcel を試す
    • Rust のサードパーティ製ライブラリの利用
    • Parcel を採用する際のデメリット
    • 本節のまとめ
    • 参考文献
  • Webpack の利用
    • Webpack を試す
    • WebAssembly から JavaScript の関数を呼び出す
    • Rust のサードパーティ製ライブラリの利用
    • コレクション, 文字列の受け渡し
    • 本節のまとめ
    • 参考文献
  • TypeScript との連携
    • Webpack プロジェクトへの導入
    • 本節のまとめ
  • 関連ツール・サービスの紹介
    • alexcrichton/wasm-gc
    • ashleygwilliams/wasm-pack
    • WebAssembly Studio
    • koute/cargo-web
    • DenisKolodin/yew

書籍自体の開発について

本書は GitHub 上で管理されており, MIT License にて公開されています.

github.com

ここでは書籍自体の開発に使用したツール, サービスを紹介します.

電子書籍の作成に VuePress を使用しています. VuePress は技術文章向け静的サイトジェネレータです. 似たような技術文章向け静的サイトジェネレータに GitBook などがありますが, それらに対して VuePress は DOM のレンダリングVue.js を使用しているという特徴があります. そのためドキュメントの Single Page Application (SPA) 対応, ドキュメント内での Vue.js コンポーネントの埋め込み, デフォルトのコンポーネントの拡張などの機能が提供されています . また, Google Analytics の統合や rogressive Web Application (PWA) のサポート *2 などの機能もあります.

本書は VuePress により SPA が有効化されており, 画面遷移がこれでもかという程滑らかになっています. 是非体感してみて下さい. ちなみに本書では PWA は無効化しているのでご注意下さい.

vuepress.vuejs.org

qiita.com

本書は VuePress により拡張された Markdown 形式で書かれており, Prettier によるフォーマットが適用されています. 執筆中も エディタのプラグインと連携して Markdown を保存する度にフォーマットが適用されるため, 快適に執筆できました.

prettier.io

書籍のデプロイには Netlify を使用しており, git push する度に自動で Netlify のサーバ上で書籍がビルド・デプロイされます. npmYarn の強力なサポートのお陰で数クリックでデプロイ出来る上, SPA のサポート, コミット / ブランチ / PullRequest ごとの Deploy Previews の作成などの機能があります.

www.netlify.com

著者への寄付について

本書は著者の春休みの 1 ヶ月間とゴールデンウィークの 1 週間, 合わせて約 40 日間を費やして執筆されました. もしあなたが本書を読んで著者の活動に関心を持ち, 支援したいと思って頂けたのなら, 本書の 著者への寄付 の節にあるリンクから著者に寄付できます. 寄付は著者の今後の活動に有効に活用させて頂きます 😄 *3

おわりに

以上が WebAssembly 開発環境構築の本の紹介となります. いかがでしたでしょうか. 本書を読んで WebAssembly を触る人が 増えてくれると良いなと思っています. それと, Twitter などで #WASMの本ハッシュタグを付けて感想や意見などを書き込んでもらえると著者が喜びます.

それでは WebAssembly 開発環境構築の本 をよろしくお願いします.

*1:当該の Web アプリケーションはまだ完成していませんが, 完成次第別の記事で取り上げる予定です.

*2:技術文章ごときに PWA が必要なのかという疑問はありますが, オフライン環境下でタブレットなどを利用する場合は有用かもしれません.

*3:漫画や Blu-ray Disk も著者の今後の活動に活用されます 😛

遅刻可視化ツールの紹介

はじめに

個人開発で遅刻可視化ツールを作って Dentoo.LT #19 で話してきたのでその紹介です.

www.slideshare.net

遅刻がテーマということでアイコンはナマケモノをモチーフにしたポケモンである「ナマケロ」にしました. ちなみに「Slakoth」はナマケロの英名です.

モチベーション

  • 大学生活において1日の内最初の授業にどれくらい遅刻したかを可視化したい
    • 生活習慣という面で1年を気軽に振り返りたい
  • ちょっとしたデータ分析をしてみたかった

概要

Googleロケーション履歴*1」の生データを利用して通勤, 通学の遅刻をチャートで可視化できます. ツールにロケーション履歴をJSON形式で読み込み, 始業時間や通勤先/通学先を設定すれば, それを元に遅刻回数/遅刻時間/遅刻率をチャートで可視化してくれます.

使い方

  1. 事前に 自分のデータをダウンロード からJSON形式でGoogleロケーション履歴の生データをダウンロードしておく
  2. I Found Slakoth!!! にアクセス
  3. ロケーション履歴の読み込む からJSONファイルをツールに読み込ませる
  4. 始業時間を追加 から遅刻の基準となる1日の最初の授業開始時刻や始業時刻を入力する
  5. 必要に応じて 始業時刻一覧 から 3 で入力した時刻を編集, 削除する
  6. 通勤先/通学先の設定 から図形ツールを使って通勤先/通学先の領域をポリゴンで囲う
    • 検索ボックスから場所を検索してそこに飛べる
    • 頂点をドラッグで頂点を移動
    • 頂点と頂点の間にあるグレーアウトした丸をドラッグすると頂点を追加
    • 頂点を右クリックで頂点を削除
    • ポリゴンをダブルクリックでポリゴンを削除
    • ポリゴンは複数個作ることができる
    • 右上のボタンを押せば全画面で図形ツールを操作できる
  7. チャートチャートを出力 ボタンから入力したデータを元にチャートを生成
    • チャートで表示できるデータの種類は 遅刻回数/遅刻時間/遅刻率 の3つ
    • 月ごと, 週ごと, 曜日ごと の3つの分類方法が選択できる
    • 下に表示されているバーを弄ればチャートに表示するデータの期間を範囲指定できる

裏でロケーション履歴をどっかに転送して盗み見るなんてことは一切していませんが, 怖いなと思った方はオフライン環境下でやると良いです. まあそもそもツールを使わないというのが一番安全ですが.

f:id:mizdra:20180314232328g:plain
デモ用のロケーション履歴を用いたチャートのデモ

応用

  • 通勤先/通学先を職場や大学以外に設定してみる
    • 例えば電車通勤・通学者であれば最寄り駅の先の駅をポリゴンで囲っておけば寝過ごし回数を数えることができる
    • 北海道には何回行ったか, 海外には何回行ったかなどを調べることもできる

下の画像は僕のロケーション履歴を用いて可視化した「帰路における寝過ごし回数」です. この時期は試験で忙しかったんだなとか, この時期は余裕があったんだなとかが分かって便利です.

f:id:mizdra:20180314232849p:plain
帰路における寝過ごし回数

技術面

アプリケーションを作る上で利用したライブラリなどを書いておきます.

おわりに

*1:AndroidiOSGoogleロケーション履歴を有効化しておくと, 自動で位置情報が時刻と共にGoogleアカウントに記録できるサービスです

Vue.js+TypeScriptを試した際の雑感

Vue.js, 良いですよね. ドキュメントも充実しているし, 読みやすいし, 個人開発する分には素早く楽しく開発できてとっても良いライブラリだなと思っています.

ただ, 開発をしているとやっぱり「型が欲しい!」という気持ちが生まれてしまうものです. そういう経緯でVue.jsにTypeScriptを上手く結合しようと色々調べたので, ここではその時に出てきた雑感を箇条書きで纏めておきます. Vue.jsはダメだとかTypeScriptは悪とかではなくて, ただのメモだと思って読んでもらえればと思います. 「その問題, これで解決するよ」とか「こんな方法あるよ」とかあればコメントなり @mizdra へのリプライなりで教えて頂けるとありがたいです 🙏

前提

  • エディタ: VSCode
  • Webアプリケーションの個人開発をしたい
  • コンポーネント指向
  • 型が欲しい
    • クラッチになるのでFlowではなくTypeScriptで
  • 楽しく開発したい

雑感

要約

  • 問題が多く, まだ厳しい
  • 問題は沢山あるけど, 解決しようという動きはあるので継続して追っていきましょう

未解決の問題

解決済みの問題

代替手段

参考

2017年を振り返って

"今年"は2017年, "来年"は2018年のことを指します.


去年同様, 今年も1年の振り返りをします. 例年通り雑にやっていきます.

今年も年が明ける前に投稿出来なかった. 残念.*1

1月

この頃は去年の12月にやっていたReact+ReduxでSMの乱数調整補助ツールを作る作業の続きをしていました.

12月後半はReact+ReduxでSMの乱数調整補助ツールを作っていました. これは現在も製作中で, 暫くしたら公開できるかと思います. どうぞお楽しみに.

2016年を振り返って - mizdra's blog

結局時間があまり取れなくてこのプロジェクトの開発は停止中です… スマホから乱数調整ツールを使いたいという要望が多いのでWebアプリでサクッと作ってしまいたいという気持ちはあるので, 今後何かしらやるかもしれません. 多分…

ReduxというかFlux, この時初めて触ったのですが得られるものも大きいが失うものも大きい…という印象を受けました. ボイラープレート辛い… 最近Flux周りは一切触ってないので来年は色々試してみたいですね.

2月

2月のある日, うっかりcd src/c src/typoして大事故が発生しました.

これは, 僕のzsh環境ではalias c="git checkout"という一文字エイリアスが登録されており, c src/git checkout src/に展開されてsrc/ディレクトリの内容がHEADへと巻き戻される==コミットしていないsrc/ディレクトリの変更が吹っ飛んだという話です. git checkoutが破壊的なコマンドだなんて知らなかったんです… うう… *2

それとyysk.herokuapp.comという超便利Webサービスを発見しました. 最近はこれを使ってゆゆ式ライフを満喫していて完全にオタクです. 皆さんも一緒にゆゆ式ライフを満喫しましょう*3.

3月

Nintendo Switchが届いたので「ゼルダの伝説 ブレス オブ ザ ワイルド」というげーむをやりました. とっても楽しかったです.

あと, Dentoo.LT #16 で登壇してVue.jsの話をしました.

4月, 5月, 6月

この頃はサークルで「Scala Collection Library Code Reading」というScalaのコレクションライブラリのコードをひたすら読む会に参加していました. 4月中はScalaの基礎を学び, 5月以降からコレクションライブラリのコードを読んでいました. 僕は今までScalaに触れたことはありませんでしたが, おかげで複雑でないScalaコードであれば読み書きできる程度にはなりました. 「ListStreamの構造はこうなっているのか〜」, 「implicitってこうやって使うのか…」, 「call by need, loop detection, 戻り値同型の原則, なるほど…なるほど…」などと言っていました. 普段JavaScriptしか書いていないので関数型言語に触れられたのは非常に良い体験でした.

7月

イカを買ってしまいました*4.

Switch, 結局最近はイカ専用機になってしまっているのですが, イカは楽しいので満足度は非常に高いです. ゲーム起動して数分でサクッと遊べるの最高ですよね. 無限に時間が溶ける.

8月

この頃からEmtimerの開発をしていました.

開発の動機は既存のFlash製のタイマーをリプレースしたい等色々あったのですが, 単純にVue.jsが良さそうだったのでそれを使って何か作ってみたいなというものがありました. この考え自体は3月にVue.jsでタイマーを作る話をした時からあって, やっと夏季休業で時間が取れたので開発を始めたという感じです.

Vue.jsを触ってみた感想としてはとりあえずVue.jsが提供してくれている機能だけでも十分アプリケーションは作れるんだなあという感じです. ただ, (最新のバージョンで多少マシにはなりましたが)TypeScriptのサポートが微妙だったり, ツール周りのサポートが不十分(特にLintなどの静的解析周り)だったりしたので, TypeScriptでガチガチにやりたいならVue.jsはちょっと辛いかも…とは思いました. まあ公式もこのあたりの問題を改善しようと努力しているようなのでいずれ時間が解決してくれると思います.

それと家のトイレが新しくなりました. 扉を開けたらパカーッと便蓋が開くすごいやつです. 便器の中が光ったりします. ピカー.

Dockerの勉強もしました.

mizdra.hatenablog.com

9月, 10月

Headless ChromeのラッパーライブラリであるGoogleChrome/puppeteerが公開されたので, それを使って自動車学校の技能教習の予約が空いたら通知するスクリプトを書きました.

mizdra.hatenablog.com

そう言えばウェブスプレイピングやるの初めてでしたね. 個人的に満足のいくものが出来たので良かったです.

11月

11月は8月からコツコツ作っていたEmtimerを公開しました.

RT: 170+, Like: 350+(記事執筆時点) と非常に多くの反響がありました. ありがとうございます🙇🙇🙇 お陰様でEmtimerは40日程で約4000ユーザ*5が利用しています. セッション数にすると約1.4万件です. 今後も開発を継続していく予定ですので, どうぞよろしくお願いします.

mizdra.hatenablog.com

12月

Pokémon RNG Advent Calendarの季節です!!! 今年もやりました!!!

adventar.org

今年も無事埋まったので本当に良かったです*6. めでたい 🎉🎉🎉 参加してくださった方々, ありがとうございました🙇🙇🙇

僕が書いた記事は以下の3つです. 是非読んで下さい.

アニメを振り返る

今年からアニメの振り返りもしてみようと思います. 僕がこの1年で観たアニメで「良い」「良すぎる」などと感じたアニメを列挙するコーナーです. *7

良い << めっちゃ良い << 良すぎる << 最高 の順で評価が高いです.

秋は最高だった… 特に宝石の国は毎回最高って言っていた記憶があります. 早く2期が観たい…

GitHubを振り返る

去年

f:id:mizdra:20170101003302p:plain

今年

f:id:mizdra:20180101002819p:plain

去年から80 contributions程増えました. めでたいですね. 8月〜12月は大体Emtimer関連のcontributionsでした. この調子で来年も頑張っていきたいと思います.

おわりに

2017年は沢山頑張った気がします. 最近は自分の技術力が上がってきて開発スピードが以前よりかなり速くなったのを実感するようになりました. 良いことです. 2018年は2017年よりさらにやっていきを加速させていきたいと思います*8. 2018年もやっていきましょう.

*1:3年連続年内投稿失敗している気がしますが気のせいでしょう.

*2:この事故が発生して以降, 「alias c="git checkout"」は削除しました

*3:姉妹サービスに zoi.herokuapp.comがありますが, 記事執筆時点では落ちているようです. 残念…

*4:この行為が後にあんなことになるとはこの時はまだ誰も知らなかった― (イカのやり過ぎで無限に時間を消費するやつです)

*5:Google Analyticsより

*6:枠が予約されているものの書かれていない日がいくつかありますが, 気のせいです. 気のせいです.

*7:ちなみに僕が見たアニメはanimetickで管理しています.

*8:流石に雑すぎるので具体的な例を書いておくと, WebAssembly, Flux, サーバサイドあたりを触ってみたいと思ってます