めろたんのアレ

色々書いてくやつ

Coinhiveのアレについて思うこと

注意

このブログをご覧になると、閲覧者様の端末のCPUやメモリ等のリソースを使います。
高負荷がかかる可能性は基本的には無いかと思いますが、ご利用なさっている端末のスペックによっては、一時的に端末が重くなったりする可能性があります。
また閲覧者様によっては意図していない挙動をする可能性があります。
ご了承頂ますようよろしくおねがいします。


うぇい

皆さんにリソースを使うことを明記したので、この記事が原因で検挙されることは無いでしょう!

先日例のCoinhiveの事件で思うところが多々あったので、仕事終わってから爆睡してて起きてから眠気眼で point-hive っていうのを作ったものです。

反響がすごくてビビったりしてましたが、PRとかISSUEとか来て面白かったです。

github.com

さて、そもそもこれを作ろうと思った理由なんですが、高木浩光氏のブログに思考実験について書かれていたので、まぁそんなむずくもなければ考えるところもなにもないのでやっとくか。と思ったところからでした。

高木浩光@自宅の日記 - 懸念されていた濫用がついに始まった刑法19章の2「不正指令電磁的記録に関する罪」

「自分のパソコンのCPUを勝手に使われる」ことと「マイニングさせられる」こととが連なって初めて不正なものとなるのであろうか。それぞれ単独では不正でないのに? ここで考えてみたいのは、以下のツイートをする人がいたように、マイニングせず、ただ空転するだけの無限ループを設置したWebサイトの公開は犯罪なのかという思考実験である。

無限ループで無用にCPU負荷を食ってしまうWebサイトは、バグとして従前からあり得たであろう。それを放置していたからといって犯罪になるとは、これまでのインターネット史の中で誰も言っていなかった。仮に今から故意にそのようなサイトを作って公開したら、警察は摘発するつもりなのだろうか。さすがにどんな田舎警察でもそんなことはしないだろう。

これですね。

これにそそのかされて作った!僕に責任は無い!!!って言いたいわけじゃないのであしからず。

で、公開したら前述したとおり意外と反響がすごく、記事でとりあげられていたりしてびっくりしました。

gigazine.net

internet.watch.impress.co.jp

とまぁいろいろ取り上げられていたので、思っていることをガーッと書こうかなーと思い書いています。

Coinhiveの何が"ダメ"なのか?

今回問題になっているCoinhiveですが、なぜ"ダメ"なのでしょうか。

警察庁Twitterで投稿していたのでそれを見てみてみます。

*1

詳細な情報をみるためリンクへ行く

仮想通貨を採掘するツール(マイニングツール)に関する注意喚起

マイニングツールは、パソコンの処理能力を活用し、仮想通貨を得るためのツールです。同ツールが設置されたウェブサイトにアクセスした場合、ウェブサイト運営者が仮想通貨を得るために閲覧者のパソコンの処理能力が利用されることがあります。

そうですね。

マイニングツールを設置することを検討しているウェブサイトの運営者 自身が運営するウェブサイトに設置する場合であっても、マイニングツールを設置していることを閲覧者に対して明示せずにマイニングツールを設置した場合、犯罪になる可能性があります。

なぜ?何罪?どういう罪なんでしょうか?

インターネット利用者 マイニングツールが設置されたウェブサイトにアクセスすることで、パソコンの処理能力が意図せずに使用され、パソコンの動作が遅くなるなどの事象が発生する可能性があります。意図しない状況で急激にCPUの利用率が高くなるなどの事象が発生した場合には、ブラウザを閉じることで事象が収まるときがあります。

意図とはなにか。誰の意図なのか主語がわからない。主語が『利用者』であれば、メインコンテンツ以外に処理能力が使われるのは意図していないのでは?*2
大半のWebサイトはもちろんのこと、この世のアプリケーションの大半は意図していない処理が発生することになるのではないだろうか?
広告はもちろんのこと、例えばPCの起動時に「ようこそ!」とか表示するのなんてなにに処理能力使ってんだよ!起動に全力を尽くせバカ!となるのでは?

とまあ結局なぜ"ダメ"なのかよくわからない。

ここから読み取れるのは「利用者の意図していないところでPC・スマホ等の処理能力を使うと犯罪になる可能性がある。」ということかなと僕はそう読み取った。

いや無理でしょwww

利用者がどういう意図でWebサイトにアクセスしてくるかなんてわかるわけ無いやんw

利用者「そんなアニメーションいらないし、勝手に処理能力つかわれた。警察〜〜〜。検挙してくれ〜〜〜〜⤴」
ってきたら対応すんの?しないよね?

とまあよくわからんのですわ。でもあのページを見るにそういうことしか読み取れないし、それでも結局罪名とかはわからないし…。

ということで例の神奈川県警に問い合わせたのだが、今の段階(2018年06月16日19時)ではまだ返事が来ていない。多分色んな所から問い合わせがきて大変なんだろう。

結果何がダメかわからん。

つまり僕は何もできないのでは?

警察庁に書いてあるものをそのまま受け取ると、「マイニングツール等処理能力を使用することを明示しなければダメ」という感じっぽい。

で、Webサイトはアクセスしたときから処理能力などなどを使うわけです。明示もクソもないし、同意の余地もクソもないんですよ。

クッションページ(処理能力を使うと明示、同意をさせるだけのページ)とかを用意しても、そのクッションページは意図していないので意図していないところで処理能力を使われたとなれば終わりなわけですね。
つまりWeb全般は犯罪の可能性があるということになるわけですねぇ。*3

とまあ僕のようなWeb系のエンジニアはなにも開発できない国*4になってきたなぁという感じがして正直めっちゃ困惑している。

反対というか声をあげている人たちも同じようなことを考えているのだろうと勝手におもっている。

同意云々が問題なのか?

先のpoint-hiveを取り上げてくれた記事のブコメとかに、「同意が無いことが問題なんですよ〜」と書いている人がいたが、本当にそうなのだろうか?

その記事を読むために裏で動いている各処理について同意はしたのか?
何をクリックしたかとか、どれだけそのページに滞在しているのか等をプログラムで収集していることだって全然珍しくない。それについて同意はしたのか?
広告を表示することにも同意したか??その広告を表示するのにも処理能力をつかうぞ??
そもそもその記事を読みたいだけであって他のメニューバーとか、意味のないそれっぽいフリー画像とか、その他諸々を表示・ダウンロードすることにも処理能力を使っているが全部同意してるか????

現状同意もなにもしていないはずなのに、問題視されていない「処理能力の使用」と今回の問題視された「処理能力の使用」にはなんの違いもないはず。*5

なぜCoinhiveだけ問題になる?

まとめ

Coinhiveを擁護したいわけではなく、何が違法なのかをちゃんと明示してほしいだけなのだ。

でないと僕が今後開発するものは逐一同意を取るためのプログラムを書き続けなければいけなくなる。*6

それどころか、一番最初にも書いたが、ブログですら表示するのに処理能力を使うのでそれも書かないといけないし、ツイートだってそうだし、RTやLikeしたときですら相手の端末に通知を行うことで処理能力を使うわけだ。
全部同意させないといけないのか????
それはおかしいよね。と普通なら思うと思うけど、そことCoinhiveのようなスクリプトとの違いは?
重くなるからギルティ*7なら検挙された人の中には重くならないように調整をかけていた人もいたが、それすら検挙されているけどなぜ?
他人の端末の処理能力をつかって利益を得るからギルティなら広告はなんでダメじゃないの?
重いし利益を得るからギルティってなら動画広告も爆死だし、なんかゲームができる広告とかも重くなったりするけどそれはダメじゃないの?

え?なんなの?

というわけで、僕は怒っているんですよ〜という話でした。

*1:このツイートだけ異様に反応が多くて面白いなーと思いました。

*2:というよりそもそも利用者は常に何に処理能力が使われるか気にしているものなの?僕はそんなに気にしてないけど。気にしているのなら、その割には詳しくない人多すぎない?

*3:まあ極論だし、飛躍しすぎってのもわかるが、意図しているかどうかとか同意があるかどうかとかで話されてもそうなるわ。としか。

*4:最初は"なにも開発できない世界"にしていたが日本以外はとくに大丈夫だろと思い"国"にした

*5:そりゃ計算する量が違うとかはあるが、両方共処理能力を使うことには変わりない

*6:その同意を取るプログラムを実行するための、同意をとるプログラムを実行するための、同意をとるための(以下無限ループ

*7:そもそも重くなるかどうかって端末によって違くないですか?うんこみたいなPC使ってたら楽天とかみたら爆発して死ぬんじゃない?

HTMLとCSSだけでミニゲームをつくる

うぇい。

昨日はお酒を飲んで陽気な気分になっていました。

今は厳しい顔をしながら書いています。

今回は Misoca Advent Calendar 2017 の16日目の記事です。

前の記事は

tech.misoca.jp

これでした!

merotan ( @renyamizuno_ ) が、HTML と CSS を使って究極の何かを作ったことについて語ってくれるそうです。

究極の何かを作ったので書きます。

HTMLとCSSだけでどこまで出来るか

HTMLとCSSはすごい表現力を秘めているのは皆さんご存知かと思いますが、 その御蔭でわけわからんと思うことも多々ありますね!

で「HTMLとCSSチューリング完全」という話もあったりする。

hoo89.hatenablog.com

まぁあくまでネタくらいに受け取ったほうが良いと思う。たぶん。

とりあえずそれくらい表現力があるわけなのです。

それで色々すごいものがありまして、例えばこれ。

Pure CSS3 calculator

HTMLとCSSだけで書かれている電卓なんですって。

やばくない?

電卓出来るならなんでも出来るでしょ。

と思ってミニゲームを作りました。

HTMLとCSSミニゲーム

これです!

github.com

マークアップは適当&CSSとかclassの命名規則とかも適当!動けば良いんだよ!()

f:id:renyamizuno:20171216190331p:plain

以下のリンクからであそべます。 スタート後、赤い丸をクリックするゲームです。 左上にポイント、右上に制限時間があります。

https://renyamizuno.github.io/minigame-only-css/

あとiframeでも

スマホだと見れないかも。 HTML見てもらえばわかりますが、JSは一ミリもありません。

どうやってうごいているか

いろいろ説明しないといけないところがあるので、個別に書いていこうと思う。

タイマー

ゲーム画面右上のタイマーについてはどうなっているかというと、

  <div class="mini-game-timer">
    <div class="mini-game-timer__a">
      <div>
        <div>0</div>
        <div>1</div>
        <div>2</div>
      </div>
    </div><div class="mini-game-timer__b">
      <div>
        <div>0</div>
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
        <div>5</div>
        <div>6</div>
        <div>7</div>
        <div>8</div>
        <div>9</div>
      </div>
    </div>
  </div>

HTMLはこうなっている。 タイマーで使う数値を全部書いている。

実際にどう数値を動かしているかというと

.mini-game-timer__a, .mini-game-timer__b {
  display: inline-block;
  position:relative;
  overflow: hidden;
  height: 24px;
  width: 12px;
}

.mini-game-timer__a > div, .mini-game-timer__b > div {
  position: absolute;
}

.mini-game-timer__a > div {
  animation: timer-mekuri-a 30s steps(3) 1;
}

.mini-game-timer__b > div {
  animation: timer-mekuri-b 10s steps(10) 3;
}

@keyframes timer-mekuri-a {
  0% { top: -48px; }
  100% { top: 24px; }
}

@keyframes timer-mekuri-b {
  0% { top: -216px; }
  100% { top: 24px; }
}

こんな感じ。 animationをつかって動かしている。

stepsを使うことで、ステップで動かすことが出来るので、それでうまくやっている。

スコア

これの説明が大変。

まず的からかな。

<input id="target1" class="point" type="checkbox">

<!-- .... -->

<label class="target" for="target1"></label>

的の構成はこんな感じ。 labelが実際の的になっている。

.target {
  position: absolute;
  top: calc(50% - 13px);
  left: calc(50% - 13px);
  width: 26px;
  height: 26px;
  background: red;
  border-radius: 50%;
}

.target[for="target1"] {
  animation: target1-animation 5s infinite;
}

#target1:checked ~ .stage--main > [for="target1"] {
  background: blue;
  pointer-events: none;
}

@keyframes target1-animation {
  0% { transform: translate(100px, 50px) }
  50% { transform: translate(50px, 100px) }
  100% { transform: translate(100px, 50px) }
}

それでCSSはこんな感じになっている。

的を画面中心において、animationtransformをつかい位置をずらしている。

またlabelなので、labelforで指定したidの要素と関連付けが出来ることを活かして、checkboxにチェックが付くようになっている。

それでクリックされた(forcheckboxにチェックが入った)labelに関しては、pointer-eventsを使ってクリックが出来ないようにしている。

チェックが入っているかはcheckedという擬似クラスを使うことで確認できる。

それでスコアの表示の部分については、HTMLは大したことないので割愛。

body {
  counter-reset: score;
}

.point:checked {
  counter-increment: score 10;
}

.mini-game-score::before {
  content: "Score: " counter(score);
}

CSSはこのようになっている。

counterを使ってスコアを計算している。

画面の遷移

最初の「スタート」をクリックしてから「おわり」までの画面の遷移についてどうなっているかというと

<input id="game-start" type="checkbox">
<input id="reset" type="reset">
<label class="stage stage--op" for="game-start">スタート</label>
<div class="stage stage--main">....</div>
<label class="stage stage--end" for="reset">...</label>
.stage {
  position: absolute;
  display: block;
  width: 100vw;
  height: 100vh;
}

.stage--op {
  display: flex;
  align-items: center;
  justify-content: center;
}

.stage--main {
  display: none;
}

.stage--end {
  display: none;
  opacity: 0.3;
  background: black;
  color: white;
  font-size: 36px;
}

#game-start:checked ~ .stage--op {
  display: none;
}

#game-start:checked ~ .stage--main {
  display: block;
}

#game-start:checked ~ .stage--end {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  animation: game-end-animation 30s;
}

@keyframes game-end-animation {
  0% { visibility: hidden; z-index: -1; }
  99% { visibility: hidden; z-index: -1; }
  100% { visibility: visible; z-index: 100; }
}

こうなっている。

「スタート」は的と同様の作りになっています。

チェックが入ったらゲームの画面が表示されます。

同時に「おわり」の画面も"表示"されますが、visibilityを使い非表示にしています。 またz-indexを下げてゲームの画面に覆いかぶさらないようにします。

30秒立つと「おわり」の画面をanimationで、z-indexが100になり、またvisibilityで表示するようにします。

「おわり」の画面は的と同様にlabelとなっていて、for<input type="reset">に向けます。

resetは、クリックするとform要素内のinputを初期値に戻します。 これによりスコアはリセットされ、また「スタート」の画面が表示されるようになっています!

まとめ

つかれた。。。

なんだかcounterとかpointer-eventsとかさ、お前らまじでCSSなの?大丈夫?みたいなこと思ったりしたけど、まぁ便利なのでいいんじゃないかな〜(ハナホジ

とりあえず、これぐらいのことは結構普通にできるんやで〜CSSすごいな〜って思いました。

みんなもHTMLとCSSだけで面白いものつくっていこうな!!!!

あしたはえんださんが「日報bot」について書いてくれるそうです!楽しみだな!

"PDCA"を簡単に高速に綺麗に回す方法

うぇ〜〜い

いろいろあったのに更新はなかったんや。

とりあえず今回は、Misoca Advent Calendar 2017 の4日目に参加していて完全に忘却していたのでヒイヒイいいながら書いています。

間に合え!!!

前回の記事はこれでした!

tech.misoca.jp

明日は、 merotan こと @renyamizuno_が「すごーい」何か書いてくれるそうです。楽しみです。

ヒェ...

PDCAを回す

今年を色々振り返ってやはり流行の廃れるスピードがスゴイなぁ(小並感)と思うのですが、今年流行ったものとしてハンドスピナーとかありましたね。

そのなかで、

togetter.com

こういうのがありまして、

今回はこれをウェブでやっていくぞ!!!!!

というやつです。

釣られた人は釣られたクマーして。

プロトタイプ

See the Pen めっちゃPDCAまわしてる by renyamizuno (@renyamizuno) on CodePen.

雑にね。

イメージこんな感じ。

で普通にやるだけだとつまらないので、Web Componentsをやってみる。

あ。ちょうどここに「イヌでもわかるWeb Components」っていう本があるぞ〜⤴

inutetraplus.booth.pm

(興味がある方はポチッとお願いします🙏)

と露骨な宣伝をはさみつつやっていきます。

やった。

PDCA Rotate

ここでみれる。

github.com

コードはここ。

回し方は簡単。

コードはたったの2行。

<link rel="import" href="./components/pdca-rotate.html">
<pdca-rotate rpm="30" rotate-direction="normal"></pdca-rotate>

これだけで最後まで回せます。

簡単!!!!!

rpmを上げることで高速で回せます。

高速!!!!!!

回し続けてもブレることはありません。

綺麗!!!!!!!!

すごい!!!!!!!!!

はい。

早すぎると止まったりしますね。

技術的な話

大したことはしていないのですが、 最初にも書いたとおり、Web Componentsの技術を使っています。

template要素を使ってテンプレートを作り、「回る」だけのコンポーネントを作ます。 components/rotate.htmlがそれです。

同様にPDCA Spinnerのテンプレートを作ります。 さっきのrotateを使い、「PDCA」の各文字の部分と全体を回します。 文字は読めるように、全体の回る向きと反対方向に回すようにしています。 この辺の回る向きとかはCSSCustom Propertyをつかって良い感じにしています。

PDCA Spinnerrpmとかrotate-directionを受け取れるようにして、簡単に回るスピードや向きを設定できるようにしました。

詳しくはコードをみてくれ〜〜〜⤴

ピュアなJSとCSSとHTMLで書いているので、 Web Packする必要も無いし、ビルドもする必要もないし、 ナウいブラウザならよしなに動く(動くとは言っていない)ので、ためしてくれ〜。

動かない場合は多分Chromeじゃないからだと思うので、

github.com

これを使えば良い感じになるぞ⤴

まとめ

  • Web Components最高。
  • PDCAは簡単に高速に綺麗に回せる。
    • しかしWeb上に限る。
  • アドベントカレンダーは前々からちゃんと書いておこうな。

次回はぴーみずこと@mzp氏が「NGK2017Bの報告書く」とのことです!! 乞うご期待!!!!

Web Audio でシンセを作った話

どうもー

最近は暑くて死にそうです。

高山に行ったんですけど、22℃とかでくそ涼しかったです。

www.instagram.com www.instagram.com www.instagram.com www.instagram.com www.instagram.com

小京都だぞ!という感じがありノスタルジーに浸れたり、山の方に行けば綺麗で景色も見れて最高に涼しくて、最高に最高でした。

奥飛騨に別荘を建てて夏は奥飛騨に住みたい…。

そんな気持ちになりました。

はい。

高山には海の日あたりに学生時代の後輩氏達と行ったのですが、ただ遊びに行ったわけじゃなくて、開発合宿しようぜ〜とのことだったので、前々からちょっとやりたかった、 WebAudioをつかってシンセをつくるぞ〜⤴という気持ちを強く持ちながら、結構な時間を観光を楽しんだのでその進捗のNASAを書きます!!!!

Web Audio?

Web Audio API が正しいかな。

詳しくはこちらをどうぞ Web Audio API

まぁざっくりウェッブで音を扱うAPIですね。

音をだすだけじゃなくて、入力とかも扱うことができます。

でまぁもうこれをつかってシンセとかいくらでも作られているんですけど、まぁ作りたかったんです。

ロマンです。ロマン。

成果物〜

github.com

ネーミングセンスがないので、「FXで有り金全部溶かす人の顔」みたいな顔をしながら 「synse」という名前のパッケージをつくりました。

READMEはまだ無い。

でこれを使ったexampleがこちら

github.com

GitHub Pageで見れるようにしてるので良い感じにアクセスするか、 下のiframe内をご確認くだされ〜。

キーボードのa w s e d f t g y h j kをおすことで音がなります。

一応鍵盤通り?な配置で1オクターブが良い感じになるようになってるはずです。

同時に押してもオシレーターが一個しか無いので、単音しかなりません。

和音を鳴らしたいときは、後述するけどがんばれ。

他のいろいろな input は色々いじってもらうとアナログシンセみたいな感じに音が変わるかと思います。

設計思想とか?

そんなたいそれたものではないけど…

一応、あくまで一応、アナログシンセをイメージして作りました。

vco vcf vca とかをモジュールとして提供する感じにしています。
なので、vcoをそのままspeakerにつなぐこともできるし、vco -> vcf -> speakerのようにvcaを飛ばしたりとかもできるようになってる。

今は無いけど、もうちょっとしたらmixer?というか

vco ->  mixer -> vcf ....
vco ->

まぁmixerかな…。なんだろ…。
みたいに感じにn個の音源を混ぜるみたいなのも作ろうと思ってる。

実装的な話

Flow type とか Type Scriptとかを使って型がほしかったけど、開発合宿で2日くらいしかないし、まぁ後にしよーと思って結構ツライなぁとなってた。素直に入れればよかったけど、webpackとかで苦しんでいたので、そんな余裕はなかった。

そのうち Flow typeをいれたいなぁと思っている。

で、vcoとかはAudioNodeっていうクラスを継承させて作っていて、そこで他のAudioNodeとつなげるところは共通化させている。

vcaだけはちょっと特殊で、時間が経過するに連れて音を大きくしたり、小さくしたりみたいなのがあったので、どうしようか迷いに迷って、setTimeOutを使うようになっている。

よくないなぁ…と思いつつ、web上でのkeydownとかのイベントの発火が押しっぱなしだとワンテンポ遅れたりして、音が急にでかくなったり、いきなり消えたりしてわけわからんくなってしまったので、ダサいけどそうなっている。

今でも微妙なときがあるのでカイゼンの余地がある。

またsynseで提供している、keyboardは単音?1音?しか出せないようになってます。和音は出せません。

なぜならアナログシンセを設計思想においているからです。

和音を出したいときは、ナウいシンセのように複数個オシレーターを準備してやればいいかなと思ってます。*1

まぁvcoをn個用意してやればいいですね。

そのうちmixerができるから良い感じにつなげれば完成ですよ〜和音でますよ〜。

ちょっと話がそれましたね。

またkeyboardの実装もだいぶ汚いものになっています。 こちらもvcaと同様にsetTimeOutがあります。理由はvcaと同様です。辛かったし今もツライ。

そんな感じかなー。

色々もやっとしてるところはあるので、良い感じにしていきたいにゃーって思ってます。

あーあとテストとかも一切ないのでうーんってなってるけど、 これどうやってテストするんだ…ってなってる。 音が鳴るとか、ね。*2

まとめ

  • 高山はめっちゃ良いところだった。
  • web audio api 奥が深い。
  • つらいこともありますが、たのしかったです。

はいー

まぁそんなに使うタイミング無いかもしれないですけど、こういうのやっぱりおもしろいなぁーと思いましたまる。

そんなかんじで、ここまで。

またねー。じゃあねー。

*1:本当にそういう実装というか作りになっているかは知らないけど、多分そう。

*2:なんかでweb audio apiをモックして良い感じの値が来てるかどうか。みたいな感じのテストにすればいいのかな?

PostHTMLのプラグインつくったぞーって話

どうも。

いろんなことに夢見て、そのたびに期待をアレされて悲しくなってるめろたんです。

最近はクリエイターズマーケットっていうイベントで購入したテラリウムを見て心を癒やしています。

はい。

今回はPostHTMLプラグインつくったぞーって話を書こうと思います。

PostHTMLって?

と本題に入る前にPostHTMLってなんぞって話なんですが、

github.com

PostHTMLとは、JSHTML/XMLを変換するツールで、HTMLをパースして、ノードツリーを操作するAPIを提供しています。

PostCSS*1HTML版ですね。

これ単体だと、特になにも起きません。

で、色々公開されている、プラグインを使うことで、HTMLを良い感じに変換したりできます。

そのままのっけるけど、

import posthtml from 'posthtml'

const html = `
  <component>
    <title>Super Title</title>
    <text>Awesome Text</text>
  </component>
`

const result = posthtml()
  .use(require('posthtml-custom-elements')())
  .process(html, { sync: true })
  .html

console.log(result)

みたいにすると、

<div class="component">
  <div class="title">Super Title</div>
  <div class="text">Awesome Text</div>
</div>

と変換されてHTMLが返ってくるっていうやつです。 (このposthtml-custom-elementsっていうプラグイン筋悪くね…ってちょっとおもったゾ…)

静的なページを作るんだけど、複数ページつくらないといけなくて、headerとかは共通につくっておきたいなー みたいなのにすごく便利では?って思ったり崎哲夫してました。

今回作ったの

で、今回作ったのはこちらですー

github.com

英語が苦手なフレンズなのでアレ。

それはさておき、何を作ったかというと、

<!DOCTYPE html>
<html>
  <head>    
    <link rel="stylesheet" href="~~~~" >
  </head>
</html>

みたいに書いたときにstylesheetを中に良い感じに展開してほしい、っていうのを作りました。

なんでいるの?とは思うかもしれませんが、HTMLメールとか?あと、AMPで中に書く必要があったりするじゃん?みたいなので、どうしても中に書きたい場合があるんすよ。

っていうので作りました。

実装はどうなってる?

非常に簡単な作りになっているのでぎっよはっぶでみてくれ、みたいなところはあるけど、まぁ軽く。

github.com これを参考にしてつくりました。

const parser = require('posthtml-parser');
const fs = require('fs');
const path = require('path');

module.exports = function(options) {
  const root = options.root || './';
  const encoding = options.encoding || 'utf-8';
  return function posthtmlInclude(tree) {
    tree.match({ tag: 'link', attrs: { expand: 'true', rel: 'stylesheet' } }, function(node) { // ①
      const href = node.attrs.href;
      let content;
      if (href) {
        const src = path.resolve(root, href);
        content = parser(fs.readFileSync(src, encoding)); // ②
      }
      return { // ③
        tag: 'style',
        content: content
      };
    });
    return tree;
  };
};

これが全コードですね。簡単な作りです。

① ノードのマッチ

ここでlinkタグかつrelstylesheetで、expandtrueのときだけ展開する処理を行うようにしています。 全部展開されると困ることもあるでしょうし、任意のやつだけ展開したいことが多くあると思うので、専用の属性を設けました。 本当はdata-~~とかにすべきなのかなぁとかも思ったけど、まぁ変換された後のHTMLが正しければいいと思うし、まぁいいやってなりました。

②選択したファイルのよみこみ

まぁとくに説明することはないですね。hrefで指定されているファイルを読み込むようにしています。 それを展開するためにcontentに保持しています。

③styleで書き出す

で、その①でマッチした所をstyleタグに変換します。 中身は②で取ってきたやつですね。

テッテレ~

完成。

まとめ

もともとはすでにこういうのあるっしょ〜とか思ってたんだけど、無くて*2、期待をアレされて悲しくなってましたが、意外と簡単な作りだったので、自分でできて良かったです(小並感)。

後々になってposthtml-include使えばよかったのでは?とか思ったけど、なんか気持ち悪いし作ってよかったなと思ってます。

今後、これも盛り上がっていくといいなぁとおもいつつ、無いだろうなぁとおもっためろたんでした。

あ、今回作ったやつnpmで公開しているので、興味がある人は使ってみてくだされ〜

www.npmjs.com

チラ裏

ここからは、愚痴等。

で今、AMPのサイトつくろ〜っと思ってこれ無いやんってなったので作ったのですが、そこまでに至る経緯がクソだったので書いとく。

まず最初 Webpack3出たし、Webpackでやろ〜とおもってposthtml-loaderっていうの使おうと思ったんだけど、

github.com

これね

f:id:renyamizuno:20170702001855p:plain

f:id:renyamizuno:20170702001907p:plain

リリースに載ってないバージョンがリリースされてるんすよwwwwww

しかも壊れてるんすよwwwwwwwwwwww*3*4*5

これ特定するのにまじで精神と時間をすり減らしたから訴訟したい(暴挙)。

で諦めて、cliをつかってみようと思ったら、そっちもうまく動かなくて、精神と時間を溶かした人の顔になってた。

結局posthtmlを叩くjsを書いた。

この時の僕の気持ちは最高にアレだった。

頼むから壊れたままにするのはやめてほしい。

そんなアレでした。

とりあえずnpm界隈はこれだから〜みたいな感じになった。

*1:CSSをパースしてASTを吐いてそれを操作するAPIを提供しているJSのやつ。めっちゃ好き。ロゴがイカしてる。 github.com

*2:ちゃんと探せていないだけかもしれない

*3:もしかしたら使い方が違うかもしれないとかそういうやつかもしれないけど、4時間近く色々試したし、loaderのコードに色々差し込んで確認したりしたから確固たる意志をもって書く。僕は間違っていない。

*4:parserを指定できるので、pug(jadeって言われてたやつ)をつかってみよーと思ったら、

だけ出力されてキレてた。

*5:どうも、parserにoptionを渡す前提で作られていないので、optionを受け取る前提で作られているparserにはoptionを受け取るところで、html(というかpug)の文字列が入ってきちゃって、処理すること無く空を返すみたいな感じになってたっぽい。深くは見ていない。

第1回 React.js 導入事例で話してきた

どうも。

ちゃんとしたブログを作ろうと思ってずっと何も書いていなかっためろたんです。

ちゃんとしたこと書こうと思います。

第1回 React.js 導入事例で話してきました。

第1回 React.js 導入事例で話してきました。

frontend-temple.connpass.com

これです。

大体僕のぐちみたいになってしまっていたけど、まぁよかったかなって思ってる。

speakerdeck.com

発表資料は上のやつ。

僕のメールアドレスが隠れてなかったりしてちょっと焦ったりしてた。

準備不足ですね。

はい。

発表したってことはここまでにして、内容とかを書いていきたい。

よかったこと

まぁこの辺はホント色んな所に書いてあるとおりでそれ以上のことはないかなと思います。

DOMの操作がなくなる?

基本的にはなくなると思う。

実際やってると厳しいところが出てきて直接触らないといけないところが出てきたりするしね。

github.com

例えばこれの、

document.addEventListener('click', this.handleClickOutside, true);

これとか。

どうなん?

DOM操作では無いけどなんか怖くない?

まぁはい。

どのJSからどこを触ってるかわかる

JSXでかけば基本的にはそのJSX内で触るところが限定される(はず)だから色々わかりやすくはなるなぁという感じ。

なういJS

ES2015+ で書かないとどう書くのか全くわからん。強制的に今時な(?)JSを書かざるをえないのかなと思っている。classが本当に良いかどうかはおいておいて。

まぁ変にprototypeを書いて大変な目に(継承とか)あうよりかは良いんじゃないかな。

と言うか各ブラウザ氏class構文サポートしてたの今知ったわ。

Can I use... Support tables for HTML5, CSS3, etc

コンポーネント

なるね。 JSXだしね。

良いところはまあよくよくあるこんな感じだなぁーって思ってた。

はい。

やだなー

依存パッケージ

まぁこれはReactには直接的には関係ないんだけど、色々大変だよね。 react-routerの件とかね。

あと npm とか yarn のパッケージの持ち方がわからん。

調べろよ。って話なんだけどね。

Redux

ReactやるならReduxだよね〜SPAだよね〜〜〜〜〜 みたいなの多すぎませんかね。

そもそもFluxレスでReactやってもいいんじゃない? 何かの編集フォームだけReactとか。何かの一覧ページだけReactみたいにやっていいんじゃないかなぁっておもってる。

あと、Redux以外になんかあっても良いんじゃないかなって思う。

僕の後の えるきちさん の発表でFlux自体は割りと簡単にできる。っていうのもあったし、 一家に一台Flux実装みたいなのがあっても良いんじゃないかな〜っておもってる。 極論だから別に良いんだけど。

あとReduxだとAsyncFunctionがうまく扱えないみたいなのがクソ辛くないですかね。 なんかそんな気持ちがもやもやするけど、Reduxだけが育っていく現状。自分もReduxを使ってしまうというアレ。

ReactとかRiotとかVueとかがかつて色々マウント取り合っていたのに、Reduxは何もなかった印象。あくまで印象ですがね。なんかもうちょっと戦いがあっても良いんじゃないかなって。

SPAつらい

つらい。 なにが必要なのかわからんし、どこまでハンドリングというか面倒みないといけないんだろうって考え始めるとキリがない。

というかブラウザというアプリケーションの上でアプリケーションを作るのって辛くない? みたいな気持ちが最近は大きい。 素人がやるもんじゃねえって思った。

個人的につらいなぁ嫌だなって思ってたのがこの辺ですね。

最近思っていること

そもそもReactでやる意味

なんでReactでやりたいのか、やるのか。 というのを最近振り返ってみたところ、全くといっていいほどなんもねえなぁと思った。

ReactでやればReactNativeがあるゾ。ってあるけどそこまで魅力に感じないんですよね。個人的なアレだけど。 そうじゃなくてWebしかやらないんだよなって人はちょっと考えてみるといいのかなぁって思う。

仮想DOMがほしいなら、VueでもAngularでもあるわけで。 コンポーネント指向で〜とかでも上の2つもそうだし。みたいなね。

ReactをやるならJSXを書かないといけなくて、JSXってFacebookが考えたものでES2015+の構文とかでもなんでもないんだし、なんかどうなの?みたいな感じ。

それよか、WebComponentsっていうのがくる(ぞーってずっと言ってる気がするけど…)し、そっちに夢見たほうがいいんじゃないかなぁって思う。

Babelで最新のナウいJSを書こうぜ!ってなってるのに、次世代のWebComponents書こうぜ!みたいなのが全然無い気がするなぁって思うのが、なんだかなぁという気持ち。

僕の視野が狭いって話もある。

まとめ

完全にただの愚痴のブログみたいになってしまった。。。

ちゃんとしたブログとは。。。

とにかく、僕が言いたいのは選択肢はReactだけじゃないと思うし、SPAにしないといけないってことは無いはず。だからちょっとずつやっていけば良いんじゃないかな。

あと、もっと次世代に生きても良いんじゃないかな?って思うよ。

はい。

ここまで。

じゃあね。