メドピア開発者ブログスマートフォン用の表示で見るメドピア開発者ブログ集合知により医療を再発明しようと邁進しているヘルステックリーディングカンパニーのエンジニアブログです。Tumblrこんにちは。メドピアのRuby(Rails)化をお手伝いしている@willnetです。最近大阪Ruby会議02に妻子を連れて参加したのですが、👶が行き帰りの新幹線に合わせて寝てくれたおかげで大変スムーズに移動できました。chromeへ移行する時に気をつけることというブログエントリを書きました。chromeで実行するための設定について書いています。この設定では最近のchrome(chromedriver)では動かなくなってしましました。このエントリでは最新のやり方について紹介します。以前のブログエントリに掲載したコードを一部再掲します。chromeでのファイルダウンロード機能はデフォルトで無効だったので、有効にするために上記のようなコードを書く必要がありました。最近のchromedriver(v77以降)の仕様変更により、上記のコードは動かなくなってしまいます。新しいchromedriverでは、上記のような設定をせずともデフォルトでファイルのダウンロードが有効になっています。このとき、デフォルトではカレントディレクトリがダウンロード先になります。上記の設定がこのデフォルトの挙動に置き換わってしまうため、DownloadHelper::PATHにファイルがダウンロードされることを期待しているすべてのダウンロード関連のテストが失敗するようになります。(追記)この現象はv77時点ではlinux版のchromedriverでのみ起こるようです。macの場合はこれまでの書き方か、後述しているSelenium::WebDriver::Chrome::Driver#download_path=を利用した書き方でのみテストが通り、次の解決策で紹介した書き方だとテストが失敗します(ややこしいですね...)。次のように修正すると、ダウンロード先をDownloadHelper::PATHで設定したディレクトリに変更できます。:headless_chrome以前の設定と比べて、selenium-webdriverに対するオプションの渡し方が新しいものに変わっています。DownloadHelper::PATH.to_s)がメインの変更点です。これによりchromedriverでのダウンロードディレクトリの設定を変更することができます。...のようにせずとも次のように書くことができるようになっています(内部でやっていることは一緒です)。こちらのほうが簡潔で良い感じですね。お手持ちのchromeのバージョンに合わせてご利用ください。謝辞このエントリで紹介した内容について、@jnchitoさんに情報提供いただきました。CIが落ちるようになりました。Linux環境でのダウンロードパスの指定方法が変わったみたいです。՞)☝︎是非読者になってくださいメドピアでは一緒に働く仲間を募集しています。Tumblrみなさんこんにちは、フロントエンドピラティストの小宮山です。休養していたランニングを再開し、ハムストリングスの探求に勤しんでいるのが近況です。v-onの不思議templateでのv-onの書き方にはいくつかバリエーションがあります。なんとなく書いてもVueがいい感じに解釈してくれてしまうので普段はあまり気にしていないんですが、よくよく考えてみると不思議な挙動をしているようにもみえてきます。オーソドックスなのはこれではないでしょうか。/>methodsとして定義しておいた関数をそのままイベントハンドラとしてtemplateに埋め込む形です。}}こう書いても動作は同じです。/>見慣れたtemplate構文だと思いますが、@input="~~"の~~に書かれた処理はJavaScriptの構文としては全くの別物です。一方は関数の参照であり、もう一方は関数を実行した戻り値であるはずです。Vueのイベントハンドラとしては両者の動作は同じです。なんででしょう?不思議に思いますよね、思ってください。思ってくれたことにしてこのまま話を続けていきます。v-onの書き方バリエーションまずはv-onの書き方を種類分けしていきます。これは特に公式にそういう区分があるわけではなく、勝手に分類してみただけです。/>オーソドックスな書き方。/>引数を指定したいときに使う書き方。/>親コンポーネントにイベントを渡して行きたいときによく使う書き方。/>methodsにするのが面倒なときに使う書き方。この4種類が代表的な書き方ではないでしょうか。例示のために微妙に処理内容を変えてしまいましたが、どの書き方をしてもイベントハンドラとしては期待通りの動作をしてくれるのはみなさん御存知の通りです。v-onの書き方によるパフォーマンスの違い4種類それぞれがパフォーマンスに与える影響が気になるところです。実は先日社内フロントエンド勉強会の場でReact入門が実施され、hook周りの仕組み、特にuseCallbackによるイベントハンドラ最適化の努力にとても興味を惹かれました。useCallbackを使わない場合と比べてコードが冗長になるのは間違いないのに、それを受け入れてまで最適化に不断の努力を行うReactの姿勢には鬼気迫るものがあります。Reactがここまでやっているんだから、じゃあVueはどうなのよというのは当然の疑問です。実はこの疑問から始まってv-on周りの挙動やコードを調べて回った結果がこの記事だったりします。本題に戻り、v-onの書き方によるパフォーマンスを検証していきたいと思います。パフォーマンスの差はありません。結論がでました、この記事の本題は以上です。すみません終わりません。根拠を提示する義務を果たします。v-onのコードを読む実は当初はパフォーマンスの差があるだろうと決めつけ、ブラウザの開発者ツールでメモリ利用量とにらめっこしたりしていました。頑張っても、有意に差があるだろうと見て取れるような状況は発生していませんでした。v-onの書き方ごとのパフォーマンスグラフを貼り付けて、「こんなにパフォーマンスに差が出る!」「こういう書き方をするVue使いは素人」「これからはこの書き方一択」というマウンティングをかましていくという目論見は見事に崩れ去りました。変わり映えしない!マウンティングは失敗でしたが、なぜ差がでないのかという新たな疑問を抱いてしまうのがエンジニアの性です。差がないと性がかかってしまったなと気にし始めるのもきっとエンジニアの性です。パフォーマンス差がでない理由をパフォーマンス計測から見つけるのは難しいので、Vueの実装を探索していきます。以下ではv2.6.10タグのコードベースで紹介していきます。github.comはい、見るべきコードはここです。これが何かというと、@input="~~"の~~に書かれた文字列をイベントハンドラとして実行できる関数に変換している部分の実装です。この分岐に、先に上げたv-on記法の1と3が突入します。細かい説明は省きますが、handler.valueに上述の~~に書かれた文字列がそのまま入っています。そのままreturnしているので、イベントハンドラとして~~に書かれた関数がそのまま実行されます。1と3は関数の参照なのでそのまま実行するだけというわけです。ちなみに$emitしたときはこんな感じでイベントハンドラを実行しています。使う側には魔法に見えても、Vueの内部実装はもちろん魔法ではなく地続きの実装です。脇道にそれると、thisを付けなくてもtemplate内でmethodsを使えたりするのはここでwith(this)とされているからでした。実装を探ってみると、なるほどなぁという発見がたくさんあります。(へー便利そうと思っても軽い気持ちでアプリコードにwithを使うのは絶対にやめましょう。)再び本道に戻ります。残りの2と4はこちらの分岐で、2だとisFunctionInvocationがtrueになり、4だとfalseです。}でラップすることで、どちらも~~に書かれた処理がそのまま実行されるのが特徴です。}というラップを利用し、イベント引数を$eventという変数として受け取るなんて小技もあったりします。実は今回始めて知りましたが、ちゃんとドキュメントのこのあたりにも書いてあります。ドキュメントだとネイティブのDOMイベント用っぽいですが、非ネイティブなコンポーネントについても同じイベントハンドラの文字列パースがされているので共通で使うことができます。イベントをそのまま親コンポーネントに渡したいときのショートハンドとして使えなくもないかもしれません。/>ただし受け取れるのは第一引数のみです。b)という形にするか、argumentsを使う必要があります。@input="hoge(...arguments)"という書き方をするとbabel変換とVueコンパイラの相性が悪いのかエラーになってしまうんですが、この書き方ができる詳しい条件ご存じの方いたら教えて下さい。v-onの書き方によるパフォーマンス結論Vueの実装をざっと眺めてもうお気づきだと思いますが、今回紹介した4種類のv-on記法はいずれも同じような加工とパース処理を経て実際に実行されるイベントハンドラへと変換されます。加工とパースに若干の差異はあるものの、その後の処理に差はありません。加工とパース処理は基本的にビルド時に行ってしまいますので、ランタイムにおいてパフォーマンスに差がでることもないというわけです。}によるラップで関数呼び出しのネストが増えるのは確かです。いえさすがにその差を気にする必要に迫られる環境は皆無だと思います。今回はv-onについての調査でしたが、render関数を作って直接onの設定をした場合は状況が別物です。この場合はrenderが評価される度にそこに書かれた処理が実行されるので、ReactがuseCallbackで最適化を目指したのと同じような状況が生まれます。Vueのtemplateを使っている限りv-onのパフォーマンスを気にする必要はない、というよりしても何もできないが正しいですが、renderを使う場面に遭遇したらパフォーマンスについても気にしておくことをおすすめします。まとめv-onを使うときに気にするべきはパフォーマンスではなく、可読性。締めに入っているのに唐突に可読性という主張を始めてしまいました。templateに複雑な処理を書かないようmethodsに切り出していくことはもちろん重要です。重要ですが、その理由はパフォーマンス観点から来るものではないというのはこれまで見てきた通りです。何の観点かというと、やはり可読性ではないでしょうか。フラグをトグルだけの処理や、ただ親に$emitするだけの処理までmethodsに切り出すべきか判断に迷ったときは是非ともパフォーマンスではなく可読性に重きを置いていきましょう。՞)☝︎是非読者になってくださいメドピアでは一緒に働く仲間を募集しています。Tumblrこんにちは。Enterprise導入したよって声が聞こえてきたら、嬉しいです。speakerdeck.com櫻井こんにちは。メドピア筋トレ部、幽霊部員の櫻井です。自分は、WebAPI開発におけるスキーマ駆動開発をテーマにLT登壇させていただきました。今回のイベントのテーマがIT×社会貢献ということで、自分が担当しているサービス「kakari」についても紹介しています。・API定義のドキュメントをメンテしていくのしんどすぎ・WebAPI開発の効率を上げていきたいと思ったことが一度でもある方には、ぴったりの内容となっていますのでぜひ目を通してみてください。speakerdeck.com今回のLTでは盛り込めませんでしたが、スキーマ駆動開発を目指してみて「困ったこと、大変だったこと」についても機会があったらいつかお話できればと思っています。イベントの様子クラフトビールを用意させて頂き、イベント開始と同時にプシュ!っとして、懇親会も盛り上がりました!おわりに引き続きメドピアでは、開発で得た知見を公開するイベントを予定しております。՞)☝︎是非読者になってくださいメドピアでは一緒に働く仲間を募集しています。TumblrメドピアCTO室フロントエンドエンジニアの小宮山です、よろしくおねがいします。趣味はボルダリングとヨガとピラティスです、よろしくおねがいします。地にて開催されたメドピア開発合宿で取り組んだことについて紹介していきたいと思います。アンパサンドへのウラミツラミタイトルにも挙げたとおり、今回立ち向かったのはSass/SCSSのアンパサンド(&)です。メドピアのリポジトリはほぼSCSSで統一されているので、この記事ではSCSSの記法ベースでコード例を載せていきます。アンパサンド記法は、BEMライクなセレクタを書くときによく利用されるのではと思います。}}アンパサンドを使い、冗長な記述を限りなく減らしたスマートな書き方ですね。書いてるときはDRYなライブ感と共にスタイルを書き進めることができます。この書き方には、セレクタの検索可能性が損なわれるという非常に大きな欠点があります。上述のようなスタイル指定がされたコードに手を入れる場面を想定してみます。変更を加えようとしているファイルはhtmlとjs側です。foo</div>htmlにはheader__fooというclassを持ったタグがあり、jQueryを使ってセレクタからそのタグを取得して何かの操作をしているとします。js側$('.header__foo').hide()何の変哲もない古き良きjQueryコードです。続いてこの処理をVueで置き換えてみます。細かいところは省略しますが、こんな感じになるのではないでしょうか。}})さくっと置き換えることができ、JavaScript側はもうタグに付けておいたclassを必要としなくなりました。不要なものは消せるときに消してしまうのが正義です。header__fooというclassをタグから消してすっきりさせてしまいましょう。foo</div>と迂闊に消してしまう人はさすがにいないと信じたいです。JavaScriptから参照していなくても、CSSからclassを参照している可能性は大いに残っています。このclassに対するCSSを書いた本人なら、このclassがまだ必要であることを覚えているかもしれません。人の記憶は頼りになりませんし、このclassを消していいか迷っているのは何も知らない別人かもしれません。消したいclassがまだどこかで使われているかの判断に迷ったときは、grepするに限ります。どんな結末が待っているかはもう想像がついたかと思います。アンパサンドによる文字列結合で指定されているこのセレクタは、タグに付いているclass名でgrepしても拾われません。}}そして使われていないことを確信し、コード改善と思ってclassを消した開発者には、スタイル崩れという悲劇が待ち受けています。このようにアンパサンドによってセレクタが文字列結合されていると、タグのidやclassがどこで使われているのか見つける手段が大幅に制限されてしまいます。地道に探せば見つけられるかもしれませんが、その労力と、不要なセレクタを減らす地道なコード改善が釣り合うのかは微妙なところです。結局は触らぬ神に祟りなし、必要なのかも分からないidやclassは消えることなく未来に向かって増え続けていきます。purgecss検索妨害と仕組みは同じですが、アンパサンドによるセレクタ結合はpurgecssによる未使用スタイル削除の妨げとなる可能性があります。purgecssは非常に強力なものの、セレクタを使っているかの判定は静的解析によって為されています。どこまで正確に判定しているのかまでは精査できていませんが、不要なリスクを回避する意味でも、アンパサンドやスクリプトを用いた文字列結合によるセレクタ生成は避けたほうが無難です。合宿の地、松本にてgrepを阻害する邪悪なアンパサンドによるセレクタ文字列結合は、すでにメドピアのリポジトリ群に多く入り込んでいました。この現状に立ち向かうべく、アンパサンドを使わない素のセレクタ文字列に変換してしまおうと決意を固めます。メドピアでは年に数回、2泊3日かけて自由なテーマに取り組むことができる開発合宿を開催しています。ボリューム的にちょうど良さそうだったこともあり、アンパサンド変換用のCLIツール開発をテーマに決めて取り組むことにしました。採用言語CLIツールの開発言語にはRustを選びました。フロントエンド関連なのだからJavaScriptやTypeScriptでいいじゃないかという葛藤はもちろんあったものの、舞台はせっかくの開発合宿です。今の最善でないとしても、興味のある技術にフォーカスしてこそ開発合宿です。普段とは違う言語に四苦八苦したくなるときだってあるんです。成果物リポジトリはこちら。github.comCLIまずは当初目的通りCLIツールです。clapというCLIツール作成用便利パッケージを使うと引数解析やヘルプ表示などを簡単に作れます。pathファイルを書き換えたりといったCLI特有の機能以外はWebAssembly版と同じ動作なので、デモなどはそちらに引き継ぎます。WebAssemblyフロントエンド、Rustというキーワードが来たら当然続くのはWebAssemblyでしょう。冒頭で長々と書いた当初の目的を果たすにはCLIツールさえあれば十分ですが、舞台は開発合宿です。隙あらば気になる技術に全力投球していきます。成果物netlifyにデモサイトを用意したのでお試しください。いうのも正直なところ今回の成果物・・・作った本人から見ても実用レベルには至りませんでした、無念。「アンパサンドを置換するだけだし実装なんて簡単だろう」と気楽に作り始めてしまったのが運の尽き、Sassアンパサンド(というよりSassそのもの)は想像以上に手強い相手でした。この変換例を御覧ください。変換例みにくい!!!そうなんです。アンパサンドを解決するにはセレクタのネスト構造を解決する必要があり、そのために記述が複雑になることを避けられませんでした。ちなみに余談ですが、当初は勢いで走りすぎてこういう変換をしていました。間違い探しとしてお収めください。間違い探し制約100歩譲ってみにくさは我慢するとしても(diffが死ぬので譲りにくいですが)、仕様的に無視しにくい大きな制約もいくつか残ってしまいました。厳しいのは複数行のセレクタに対応できていないことです。見るも無残な姿になってしまいました。「1行ごとに処理すればいいだろう」という謎の自信に満ちた実装方針により、複数行セレクタへの対応が必要と気付いたときには既に軌道修正が間に合いませんでした。あと地味にSassを諦めてSCSS専用になっています。CLIとWebAssembly両対応ビルド気を取り直して、今回一番苦戦した点の紹介です。実は実装を差し置いて、CLIとWebAssemblyの両方にRustコードをビルドすることにかなり苦戦しました。RustやCargo.toml自体への理解度もあまり深くなく、試行錯誤の末になんとか形になった方法をここで紹介したいと思います。シンプルなWebAssemblyビルドRustをWebAssembly化し、ウェブページとして公開する1連の流れ自体はこちらの記事を大いに参考とさせていただきました。webbibouroku.combindgen、wasm-pack、create-wasm-appなど、便利なツールの導くままにWebAssemblyなウェブページを作ることができてしまいます。RustをWebAssemblyにビルドするだけなら解説通りにwasm-packを使うだけです。今回はもう1つのターゲット(こちらが本命のはずなんですが)としてbinaryにもビルドする必要があります。異なる依存パッケージCLIツールとしてはディレクトリ内のファイルを一気に処理させたかったので、dependenciesにwalkdirというファイル探索用パッケージを追加していました。buildコマンドを実行すると以下のようなエラーを吐かれてしまいます。`imp`原因は推測ですが、WebAssemblyにビルドできない何か(walkdirなのでおそらくファイル操作系)が混ざっていると判定されているのだと思います。その証拠に、Cargo.tomlのdependenciesからwalkdirをコメントアウトすると無事にビルドが成功します。WebAssemblyにビルドするときだけ手動でその行をコメントアウトすれば解決します!!!許されません、これは許されません。ビルドコマンドをただ実行するだけなのに、こんなにも露骨な運用でカバープロセスを挟み込むなんて許されるわけがありません。README.mdにこんなビルド方法の解説を書くこともとてもできません。本体のコーディング以上に血眼になって探し、ついにここで答えを見つけました。修正後のCargo.tomlの書き方はこちらです。bin)だけビルド時の依存関係に含めてくれるようになります。大まかな流れは上図のようになっています。buildから除外することに成功しました。binを引数に加えることで依存パッケージをしっかりと認識してくれます。引数追加程度ならREADME.mdに書くこともきっと許されることでしょう。本当はCLIとしてビルドするときにWebAssemblyでしか使わないパッケージも除外したかったのですが、こちらはwasm-packをさらに解析する必要がありそうで今回は泣く泣く断念しました。こちらの問題にも対応した完全版両対応ビルド設定の模索は今後の課題です。成果物やデモを公開するには、やはりウェブブラウザで見れるというお手軽さは魅力的です。本命のCLIツールを作り込みつつ、さくっと触れるデモをウェブで公開したいという贅沢な欲求をWebAssemblyは見事に叶えてくれました。まとめSass/SCSSの邪悪なアンパサンドへのウラミツラミからスタートし、それっぽく動くけど妥協点満載な解決ツールを作り、WebAssemblyの知見を紹介して締めるという全くまとまりのない記事となってしまいましたが、メドピア開発合宿3日間が見事に集約されています。自分で言うのもあれですが見事に集約されています。実は人生初の開発合宿というイベントでした。好きなテーマに取り組んでいいという我らがCTO福村の言葉をそのまま受け取り、このように本当に好きなことに取り組むことができた濃密な3日間となりました。これで当初目的だったアンパサンド撲滅も達成できていたら最高だったのですが、残念ながら力及ばず。なんと、同じく合宿に参加していたフロントエンドエンジニア村上(@pipopotamasu)がstylelint-scssのruleでセレクタのアンパサンド結合を禁止するというスマートすぎるPRをさくっと作って本家のルールに加えてくれました。github.com邪悪なアンパサンド勢力の拡大はこうして食い止められたのです。松本の地にて立ち上がっていたのは村上です。僕は何もしていません。持つべきものは仲間です。メドピアではフロントエンドエンジニアの仲間を絶賛募集中です。՞)☝︎是非読者になってくださいメドピアでは一緒に働く仲間を募集しています。Tumblrメドピアのサーバーサイドサウナーの川井田です。メドピアでは、年2~3回のペースで日常業務から離れて、業務改善や、技術研鑽のための開発合宿を開催しており、恒例となっています。tech.medpeer.co.jp6月26日から28日まで3日間、エンジニア13名で行ってきました!初めて参加してきたのでレポートしたいと思います。今回の合宿地は2020年rubykaigiの開催地松本です!※我々は遊びに来たのではなく、業務改善や技術研鑽のために合宿に来ております。業務より疲れるという声が聞こえてくるくらいモクモク作業していました。※我々は遊びに来たのではなく、業務改善や技術研鑽のために合宿に来ております。グルメメモリーずっとモクモクしていたら心が邪悪になります。食事を取ることでピュアな心を取り戻します。※我々は遊びに来たのではなく、業務改善や技術研鑽のために合宿に来ております。時間も忘れてモクモク作業してきた成果を社内で発表します。思いで取り組んだそうです。立ち上げたコンテナの数はちょうど100!hostsファイルには48個の*.testが追加されたそうです。カイゼンPRお待ちしてます。社員紹介アプリ急激に社員が増え、顔と名前が一致しないのをカイゼンするために、3人チームで社員紹介アプリを開発していました。コードは外部に公開されているので、ぜひPRを送ってみて下さい!github.comFirebaseを活用した猫監視システムFirebaseへの好奇心の裏に隠れる愛猫を思う気持ちがとても印象的でした。それぞれ違うアプローチで取り組んでいました。不完全燃焼に終わってしまい、3日間で成果を上げるためには、事前準備が大切であることを学びました。՞)☝︎是非読者になってくださいメドピアでは一緒に働く仲間を募集しています。