No Regrets in Bathing

カレーを週に一度食っていく

クリスマスイブのDeno

昨日テンション上がったことを書き残しておく。

ここ数日でjinjorさんがDenoを触り始めているのを興味深く眺めていたのだけど、すごい勢いでコード書いてるから、つい自分もdenoいじりたくなってしまって、イブにエディタを開いてしまった。

で、Vueの忘年会でしゅーまいさんに「Denoにないライブラリ書いたほうがいいですよ」と言われたのを思い出して、なにか書こうと思ったのだった。Denoにはライブラリがあまりないというかほぼ無である。ネタを探してnpm rankを上から見ていって、ひとまず簡単そうなものを探した。

最終的にURLをブラウザで開いたりするだけのライブラリ、「opn」をお題に選定した。スクラッチする自信はないので移植することにした。

簡単そうに思えて大変苦戦した(クロスプラットフォームは本当に面倒だな!)のだけど、一応完成して、Githubで公開した。

github.com

で、22時に公開したのだけど、その3時間後にEGOISTさんから謎のリプライが来た。

URLを開くとなんか自分のリポジトリのURLが書かれてるし、え、なにこれ、EGOISTさんわざわざ自分へのアドバイスかなにかをnow上に書いて送って来たの?と一瞬混乱したのだけど、1分くらい考えて

「あ、これ自分がライブラリ公開したのを見て、Denoのライブラリで便利に使えるWebサービスを作ったんだ、この3時間で!」

とわかった。しかもドメインまで取得して。

EGOISTさんは会ったことないし正直謎の人なんだけど、コーディングの実力と作るライブラリの多彩さは本当に人並み外れていて、尊敬しているプログラマーの一人である。図らずもクリスマスプレゼントを頂いたような気持ちになったのだった。

それにしてもEGOISTさんもDenoに興味あったのかーというのが驚きだった。(すごい賢い人だから、ざっとDeno見て一瞬で理解してimport URL冗長だなーってところだけ解決したのかもしれないけど)

jinjorさんと自分とEGOISTさんとしゅーまいさんがその日Deno絡みのコーディングしていたようだったのだけど、クリスマスイブにやることなのかどうかは完全に謎、しかし本当に楽しいんだよなー、こういうのが。

おわり。

Node.jsの次にDenoを使いたい

Node.jsの作者Ryan Dahlが作った「Deno」が面白くて、最近追っかけている。

TypeScript版Node.jsというのが雑な説明になる。yosuke-furukawaさんの下記の記事が詳しい。

yosuke-furukawa.hatenablog.com

ES Modules周りとnpmのことも考えると、まっさらから再設計したほうがスッキリしてて気持ちいいというのと、単にTypeScriptが好きというのもあるけど、今追っかけている理由は、Denoがセキュリティ的にいい感じに見えるからだったりする。

flatmap-stream事件

qiita.com

npmパッケージがビットコインの窃盗に利用される(未遂)という事件がつい先日発生した。

これははっきり言って防ぎようがない事件で、minifyしたコード内に埋められてもその差分に誰が気づくんだという話である。むしろこれによく気づいたな・・・という印象。見過ごされていてもおかしくない。

この件、自分は攻撃者以外の全員がかわいそうだな…と思った。作者がOSSに対して過大な責任を負うのも違うし、OSSのコミット権渡すときも他人の善意を疑いたくない。npm側ができることも限られている。

しかし、気軽に小さなライブラリに依存してしまう文化は、ライブラリの作者に大きな責任を負わせてしまう。

これは、誰かの努力じゃなく仕組みで解決したい問題だ。

信用できないコードを実行する

Denoのロードマップには下記のように書かれている。

We want to be secure by default; user should be able to run untrusted code, like the web. 「Webのように」信頼されていないコードをユーザが実行できるように、デフォルトでセキュアにしたい。

「コードを信用しないままに実行する」というのは今までブラウザがずっとやってきたことだ。サンドボックスがあり、ファイルへの書き込みのような危険な処理にはユーザへの承認を求める。

Denoは「脅威」として下記の2つを挙げている。

  • ローカルファイルの変更や削除
  • 情報漏えい

それを防ぐために、下記をデフォルトで禁止している。

  • ネットワークアクセス
  • ローカルファイルへのWrite
  • JS以外の拡張
  • サブプロセス
  • 環境変数へのアクセス

ファイル読み込みは許可しているのは面白いところだ。ローカルファイルを読めたところで、ネットワークアクセスがなければ漏洩することはできないので、問題ないという考えだろうか。

※2018/12/04 16:30訂正

現在は --allow-read フラグを追加する方向で話が進んでいるため、ファイルの読み込みもデフォルトは禁止になる見込みだそうです。Thanks: @kt3k

Denoはまだまだ開発途上ではあるけど、すでに簡単なHTTPサーバを書くことが可能になっている。

import { serve } from "https://deno.land/x/net/http.ts";
const s = serve("0.0.0.0:8000");

async function main() {
  for await (const req of s) {
    req.respond({ body: new TextEncoder().encode("Hello World\n") });
  }
}

main();

このコードを実行すると、下記のようなプロンプトが表示される。

f:id:hashrock:20181204004036p:plain

面倒なようだけど、これから必要になることかもしれない。

SVG + Vueで有名なsdrasさんが日本に来るよ、という話

早いもので、Vue Fes Japanまで残すところ2週間程度となりました。

で。

何はおいてもsdrasさんですよ。来日です。

このブログの読者はSVG漬けの毎日を送っていると思うのですが、 SVGアニメーションといえば自分の中ではこの方です。

Sarah Drasner(sdras)さんは、VueConf 2017(katashinさんによるVueConf 2017 参加レポート)のトリでSVGアニメーションのプレゼンを行い、注目を浴びたことが記憶に新しいです。

この方がVue Fes Japan登壇のために来日します。SVG界震撼です。

www.youtube.com

発表では「なぜアニメーションが必要なのか。そしてどのように実装すればいいのか」が楽しく解説されています。 アニメーションの制御にはTweenMaxとVue.jsが利用されています。

私もこの発表に影響されてSVGを始めたので思い入れがあります。皆さんも未見であればぜひスライドだけでも見てください。スライド内のSVGインタラクティブに動かせます。

スライド:slides.com

sdrasさんのCodepenは楽しいぞ

ウォーリーがマウスカーソルを追ってグリグリ動きます。

codepen.io

ホームボタンを押すといい感じのSVGアニメーションが展開されます。

codepen.io

聞くところによるともともとFlasherだったそうで、このへんの作品はFlashっぽいですね。

Vue.js Londonのトップアニメーションもsdrasさん作です。

vuejs.london

sdrasさんのバックグラウンド

sdrasさんのバックグラウンドは「フロントエンドエンジニア」かつ「サイエンスイラストレーター」だそうです。イラストレーターとしての作品は下記サイトで見ることができます。

https://sarahdrasner.com/

どのイラストも緻密で圧倒されます。

もともと数学とアート両方に興味が強かったようで、一旦はアート方面で教鞭をとっていたそうです。

  • San Franciscoの漫画ミュージアムリテラシープログラム(?)を教えていた
  • ギリシャのHellenic International Studies in the Arts(HISA)で絵画・写真・芸術理論を教えていた
  • フィールド自然史博物館のサイエンスイラストレーター(爬虫類と両生類)
  • ビザンティン美術を教えていた

などなど、アートの人という感じですが、その後フロントエンドエンジニアとして働くようになり、現在に至ります。

デザインと実装両面をやっているという点では、Vue.jsの作者のEvanさんと似たものがありますね。(Evanさんも元々デザインを学んでいて、エンジニアとしてGoogleに入っています)

現在の肩書はMicrosoftのDeveloper Advocateです。これはEvangelistに近いものだそうで、アニメーションやサーバレスアーキテクチャ(Azure Functionsなど)を啓蒙する立場です。

Vue.js core teamメンバーとしての活動

sdrasさんはVue.js core teamメンバーでもあります。主にドキュメント周りに貢献されていて、目立ったところでは、公式ドキュメント内の「The Cookbook」をリードしました。

クックブックはExampleよりも実用的な例を提供するためのドキュメントで、今年から導入されたものです。内容は重厚かつ実用的で、一見の価値ありです。

その他の活動

そんなsdrasさん、Vue Fesに登壇します

発表内容はまだ公開されていませんが、近日中には公開されると思います。お楽しみに! (ちなみに私はスタッフなんで、当日見れるとは限らないんですが…)

追記 2018-10-18

発表内容公開されました!「Next-level Vue Animations」ということで、アニメーション絡みの発表になりそうですね!

vuefes.jp

プログラマー絵茶を開催した&リアルタイム共同開発した

f:id:hashrock:20180720124626p:plain

絵茶というのは、お絵かきチャットの略称で、一枚の共有キャンバスにみんなで絵を描くという遊びのこと。

今回は、Twitter上で人を募って2回ほど開催してみたという話。

なぜ開催した

絵を書きたいプログラマーがTL上に増えた気がした(N=2くらい)ので、勢いで開催した。

Twitterにいる人でキャラ絵を描けるようになってみたいって人は結構いるみたいで、そういう人たちをお絵かき勢に引きずり込みたいなぁとも思っていた。

どの絵茶を使うか問題

昔ながらの絵茶はJavaFlashで作られており、最近のブラウザでは動作しづらい。HTML5ベースの絵茶を探す必要があった。

また、人気のある絵茶サービスだった「pixiv chat」は去年終了し、セルシスが提供しているkakooyo!という絵茶サービスは最大4人までの制約があるのと、PCから描くことができないという問題があった。

まず最初に選択肢に上がったのはMagicalDrawで、これはChromeから使うのであれば一番良さそうだった。

MagicalDraw | お絵かきチャットレンタルサービス

しかし最近iPad + Apple Pencilを購入してこれで書きたかったのだが、どうもMagicalDrawはiOS環境だとかなり簡素なUIになってしまうのと、スクロールの挙動が若干怪しかった。

次に見つけたのがDraw.Chatという海外のサービス。

Draw.Chat - Virtual Classroom

これはなんとビデオチャットまでできる優れもの。描いている途中にiPadで文字チャットをするのはかなりだるく、音声チャットできると楽だなと思っていたので、これは良いものだと思う。

f:id:hashrock:20180720123648p:plain

第1回はこれで開催したのだが、問題があって、描画量が多くなるとどんどん重くなっていく。スクロールするだけでリドローが発生する。

あと多機能なせいで、初見の人がUIに戸惑う。興味持って見に来ただけの人がすぐ理解できるUIだったらいいのになぁと思った。

結局自作

第二回をやるにあたって、そもそもシンプルで安定したやつがほしいという思いが出てきてしまい、結局絵茶を自作することにした。

ゼロから作るのはつらいなと思ったので、GitHubからベースにできそうな絵茶実装を探して、下記のプロジェクトを元に作ることにした。

GitHub - romebop/whiteboard: interactive drawing & chatting

f:id:hashrock:20180720124315p:plain

変更点

まずは、描画スペースを広げてスクロール可能にした。

前回開催して思ったのが、絵を描いたことのない訪問者は基本的に見るだけで描かなくなってしまうという点だった。

多分、上手い人がガリガリ描いているスペースに絵を描き入れるのは緊張するのでは、と思ったので、右側にピクトチャットもどきを実装することにした。その結果が下記。

f:id:hashrock:20180720124000p:plain

第二回

自作絵茶を投入して第二回を開催したのだが、同時に試みとして「せっかく自作なんだからリアルタイムに開発する」という企画を行った。VSCode Live Shareという機能を使って、Twitterで相互フォローしてる人なら開発に参加できる体制にした。

これにはkiyopikkoさんが応じてくれて、チャットしている裏でゴリゴリCSSを編集してUIを改善して頂いた。

最初こんなのだったのが

f:id:hashrock:20180720124926p:plain

現在こうなった

f:id:hashrock:20180720124951p:plain

この変更は開催中に本番反映された。

Live Shareでの共同開発は本当に楽しいので、みんな体験した方が良いと思う。

もう一回くらい開催したい

なかなか参加者増えないなぁという感じはあるのだけど、絵茶自体は参加してもらえれば楽しいのがわかってもらえると思うので、もう一回くらいは開催してみてもいいかなと思っている。

興味ある方は@hashedrockをフォローしてください。やるときアナウンスします。やるなら多分7/26の22:00くらいかな。

また、絵茶作成自体に興味がある方は、下記のScrapboxに参加してください。

scrapbox.io

Vue.jsのFAQサイトを作ってみた

scrapbox.io

書いてはみたものの、かなり偏った考えかもしれないので、読むときには多少警戒しながら読んで下さい。あと、色々単純化している説明もあるんですが、まずい説明になっている所もあるかもしれません。こういうの、プルリクとか受け取れればいいんでしょうね。

コンテンツ置き場にはScrapboxを使っています。Scrapboxはどちらかと言うと複数人で書く時に威力を発揮するWikiみたいなものなので、書きたい人がいたらTwitterにリプ下さい。

経緯

  • Rails等のサーバサイドの経験がある人がSPAに初挑戦して、その際にVueを選択して詰まることが増えている模様
  • 考えてみれば、サーバサイドフレームワークからSPAへのスキルセットの移行が結構きつい
    • そこで闇を抱えてSPA嫌いになる人もいるっぽい
  • そういう場合、Vueだけの解説だと足りていなくて、Node.jsやwebpackやSPA等の周辺知識も教える教材かなにか必要なんじゃないか…と思った

のだけど、書いてみてもやっぱり範囲広すぎて書ききれないなぁ、という感じでした。難しいね。

フロントエンドの教材がどこにあるのかまとめがほしい感

あと、フロントエンドの上級者と初心者の乖離が激しいなぁとはずっと思っていて、HTMLを知らない人がフロントエンドの最前線までたどり着くのは相当辛いんじゃないでしょうか。それが専門職と言えばそれまでなんですが。

N高の教材とか、かなりいい教材は点在してるっぽいんですが、フロントエンド上級者の人はちょっと戻ってきて、自分の辿ってきた道に道しるべを置いてもらえると嬉しいです。

Excelシートを憎み、愛した男

Excelシートが憎い。

Excelシートでの書類作業の辛さは言わずもがな。

  • データベースもどき
  • アプリもどき
  • 帳票出力
  • Excelシート上でのコーディング
  • エビデンス作成
  • UMLなど

以上のものについて、すべてExcelでの作成経験がある。あの世にもExcelシートを作らされる地獄がきっと存在するだろう。

Excelシートが憎い。Excelの万能性ゆえ、落とし込まなくていいものまで落とし込まれ、地獄を生み出す。みんなExcelなら慣れてるので、その他の選択肢は選ばれない。何度かMarkdownからExcelにコンバートするようなツールを書いたけれど、書式が変われば捨てざるを得ない。結局今もExcelを書き続けている。辛い。

でも待って欲しい。あれほど一括編集をエレガントにこなせるUIが他にあるだろうか(2大エディタに習熟した場合を除く)。図も書ける。式は素人でも使えるが、プログラミングの一形態ですらある。Excelやっぱり凄いよ。こんな凄いものが存在するなんて信じられない。気がつくとExcelのことばかり考えている。Excelのことが本当は好きなのかも知れない。

だから、SVGExcelスプレッドシートを自作した。車輪の再発明だ。

f:id:hashrock:20180312013009g:plain

DEMOはこちらから

ロゴも作った。

https://user-images.githubusercontent.com/3132889/37255669-e971baf2-2592-11e8-823c-0dcadcb3b772.gif

リポジトリはこちら。

github.com

すでにhandsontableという、実用的なスプレッドシートコンポーネントが存在するため、 フルスクラッチで小さく書くのを目標にしている。

下記の通り、コンポーネントは1ファイルの.vueだけで書かれており、Vue以外への依存はない(…と思ったけど、考えたらrebootに依存してた。そのうちどうにかします)。今の所413行。

vue-spreadsheet-lite/SushiGrid.vue at master · anydown/vue-spreadsheet-lite · GitHub

結構頑張って作ったけど、機能不足やバグが多数あったり、そもそもまだコンポーネント単体としてnpmから使えないとか、いろいろな不備がある。まだ実用は出来ないので、ご容赦願いたい。

SVGとVueで難しいコンポーネントを作ろう

SVGとVue.jsの組み合わせが最高なのは下記の記事でも書いたとおり。身の回りでも多くの人がVue.js + SVG遊びに興じているのを観測している。

hashrock.hatenablog.com

もっと多くの人にVueとSVGを使って欲しいので、今回は複雑なものを作る時のTipsも足しておく。

スプレッドシートを作る手順

最初はまずSVGを手書きし、プロトタイピングするのをおすすめする。

ちょっと思い出しながら書いてるけど、初期のコミットは下記のようなコードだった。

<template>
  <svg width=500>
    <rect x=0 y=0 width=100 height=24>
    <text x=0 y=12 width=100 height=24>hoge</text>
    <rect x=100 y=0 width=100 height=24>
    <text x=100 y=12 width=100 height=24>fuga</text>
  </svg>
</template>
<style>
rect{
  fill: white;
  stroke: #999;
}
</style>
  • vue createで作成されるHello.vueファイルを編集しながら作り始める。
  • この時点でロジックはまったくない。SVGのrectやtextで作りたいものが出来るのかをまず検証する。
  • ある程度要素同士にまとまりが見えてきたら、g要素でグルーピングし、transform="translate(x, y)"の形に書き直す。

それから、Vueのdataに配列を入れて、v-forで要素を生成する。

コツは、やはり見た目から先に作り込むこと。特にSVGにはz-indexが無いため、書いた順に重ね合わせされるなどの罠が存在する。 自分はDIVなどのHTML要素でコンポーネントを作るときも、まずHTMLタグでモックアップを作ってから、後でロジックを差し込む作り方をするほうが多い。

その場編集(In-place editing)

要素をクリックして、その場で文字列を書き換えられるような仕組みをIn-place editingと呼ぶ。

In-place editingは知る限り下記の3つの方法がある。

  • contenteditable属性を使う
  • クリック後、要素の上にテキストフィールドを乗せる
  • 見えないテキストフィールド(opacity=0)を最初からコンポーネント上に置いておき、クリック位置に移動する

今回のスプレッドシートは、任意のタイミングでのキー入力もテキスト入力として扱わないといけないので、3番目の見えないテキストフィールドを採用した。2番目は付箋を作ったときに採用した。

In-place editingを作るときには、特にIMEの取扱に注意が必要で、ラテン語圏のOSSIMEを上手く扱えていないケースが多い。そもそも入力出来なかったり、変換確定のEnterキーで入力が終了してしまったり。 最近は同じくIMEを必要とする中国語圏のユーザがOSSに関わることが多くなったからか、状況は改善している。

選択範囲など

SVGはz-indexによる重なり順の制御が出来ないと書いたが、下記のように分類すれば大抵のケースでうまくいく。

f:id:hashrock:20180312022916p:plain

UIレイヤーは、選択範囲やボタン、ダイアログなどに当たる。ベジェハンドルやバウンディングボックスなどもここ。

コンテンツレイヤーは、編集対象のコンテンツに当たる。今回の場合であればセルの内容。

これら2つのレイヤーを重ね合わせることで、多くの問題が解決できる。具体的にはそれぞれをSVG要素でくくり、position: absoluteで同じ位置に配置してしまう。

UIとコンテンツを同じSFCの中にまとめてしまいがちだが、そうなると表示順の罠を踏むことになってしまう。 UIのような、クリッカブルな要素がコンテンツの下に来ることは、通常ありえないので、コンテンツと完全に分けてしまうという考え方になる。

今後の予定について

Biliでバンドルを作って、npmに公開したいと思っている。機能不足を解決したタイミングで頑張りたい。

github.com

あと、ちょっと作りかけているけど、markdown tableをスプレッドシート / テキストエリアで双方向に編集できるものも作りたい。下記はスペース区切りのもの。

f:id:hashrock:20180312030806g:plain

テキストからヘッダを生成する場合は、ヘッダの幅を自動算出しなくてはならない。ちょっと考えないといけない。

おわりに

Excelを追いかければ追いかけるほど、Excel作った奴らまじで凄いという感想しか出ない。今回作ったものをExcelにするには、複数の選択領域をサポートしたり、セル内の改行や結合セル、罫線、図、数式など、とんでもないカロリーの機能を実装しなくてはならない。

だからこそ、Excelは代替されにくいのだろう。互換ツールを作ることも難しいし、そのメリットも少ない。出来の良いツールが市場に居座ることで、そのツールに依存したエコシステムが形成され、誰も逃げられなくなってしまう。

あと、ツールに対して恨みごとを言いたくなってしまうときは、やはり車輪の再発明をしてみるべきなんだと思う。今回で自分はExcelを作った人に対する敬意が少し増したような気がする。作ってみなきゃ人の苦労は分からない。

まぁ、スプレッドシートの仕事が来たら、こんなんじゃなくて普通にhandsontable使おう。ちょっとでかいけどほんと良く出来てます。

vue-cliでビルドしたプロジェクトをgh-pagesにデプロイする

vue-cliでcreateしたプロジェクトは、そのままビルドすると、出力されたdist/index.html/js/vendor.a58fe84b.jsのように、絶対パスでアセットを読みに行く。

基本的にはこれで構わないケースが大半だけれど、Github Pagesにデプロイしたい場合は例外で、プロジェクト名と同じサブディレクトリ下に配置されてしまう。そうなると絶対パスから見に行くと404になってしまい、ページは動作しない。

相対パスからアセットを読みに行くようにする

こういったケースはbaseUrlオプションを設定することで回避出来る。下記のファイルを作成する。

vue.config.js

module.exports = {
  baseUrl: "./"
};

こうすると、(先の例でいうと)index.htmlが./js/vendor.a58fe84b.jsを読みに行くようになる。

アセットが色々存在するケースでは確認していないので、これではダメなケースもあるかもしれない。

vue.config.jsについては公式のドキュメントを参照のこと。

デプロイ

デプロイはどうするかというと、gh-pagesというツールを入れるのが楽。

#インストール
$ yarn add gh-pages --dev

でインストールした後、package.jsonのscriptsに下記の行を追加する。

"deploy": "gh-pages -d dist"

あとはyarn deployを実行するだけ。

動きとしては、まっさらなgh-pagesブランチを作成して、dist下のファイルをすべて配置するのと同じになる。

Github pagesはmasterやdocsフォルダをそのままWebページとして公開出来るように最近なっているが、ビルド成果物をコミットに含めたくない場合は、firebase hostingのようなホスティングサービスを使うか、旧来のgh-pagesブランチを使う形にするのが良いと思う。ちなみにこのやり方はegoist先生がやってたやり方。