CLOSE

現場の ES201x とアーキテクチャの変遷と未来(全2記事)

WebComponentsの登場でフレームワークは死ぬのか? フロントエンドエンジニアが今知っておくべきこと

2018年2月11日、Webフロントエンドの現場とこれからをつなぐカンファレンス「Inside Frontend #2」が開催されました。Web技術の発展とともに多様化し始めているフロントエンド領域。今、それぞれの現場はどのような課題に取り組み、どのように解決しているのか? さまざまなノウハウを持つエンジニアたちが、自身の知見を語ります。トークセッション「現場の ES201x とアーキテクチャの変遷と未来」では、竹馬光太郎氏が登場。過去から現在までのアーキテクチャのトレンドを整理し、WebComponentsなどの新しい技術によってフロントエンド開発がどう変わっていくかについて語ります。

トレンドと言語の変化について

竹馬光太郎氏:いろいろ言ってきたんですけど、どういうトレンドかと言うと、やっぱりハードウェアソフトウェアが発展することによってデータをたくさんメモリ上に置くようになる。プリミティブなイベントってどこに残ってるかよくわかんないから、それを全部フレームワーク側が全部メモリ上に乗せて管理するようになる。

またそのレンダラー、ブラウザのinnerHTML、append〇〇、そういうのはフレームワーク側に全部隠されて賢いレンダラーとして実装されていく。やっぱり最初は富豪的な設計をしたあとにマイクロチューニングをするっていうことを繰り返すという世界観だと思っています。

雑な図なんですけど、テンプレーティングって富豪的な設計だなと思うんですよ。データバインディングはテンプレーティングをパフォーマンスチューニングしたもので、それをやっていくとSingle Page Applicationみたいな1 Component Applicationみたいな概念が出てくる。

だけど、それも足りなくてrequestAnimationFrameでガリガリチューニングしていって、その上に仮想DOMみたいな概念が出てきて、今回は仮想DOMの説明は一切する気ないんですけど、そうやってエンドユーザーからはよくわからない複雑な実装に近づいていくみたいなイメージです。

あと言語自体も変化してきてて、よくある図なのかちょっとわからないですけど、昔ECMAScript3書いてて、4はポシャったので5の時代になって、ES201○の時代になって、Babelが出て、Flowが出て、TypeScriptが出てというのがJavaScript系の世界観です。

ほかの言語からトランスパイルしてくる系もまだそれなりに元気で、あとJavaScriptなんて絶対に書きたくないんだから、彼らは(笑)。

(会場笑)

ScalaJSやElm、最近ならReasonというocamlからコンパイルするやつが熱いんですけど、さらにWebAssembly系と一応銘打っていて、これはまだ存在していません。おそらくこれから発生するだろうというのがC++やRustからDOMのファインディングをうまいこと作ってあげて、そっちの言語の世界観だけで表現するWebアプリケーションフレームワークというのがたぶんこれから出てくると思います。

すでにいくつかあるんですけど、quasarだったかな? RustはWeb的にわりと熱いですね。WebAssemblyがきて。

JavaScriptはTC39で毎年進化する言語になりました。多言語からはトランスパイルしてくる。WebAssemblyはみんなでがんばろうねみたいな状態です。その前にAltJSはいろいろあったんですけど、文法追加や機能提案のために行っていった結果、ES201○に全部吸収されてほぼ死に絶えました。CoffeeScriptが現場に残ってるものが多いですけど。

そういう時代を経て仕様が追いつかないものはプリコンパイラで先取りするという文化ができて、Babelでコードを書いたりして最新機能を使うみたいな雰囲気ができた。

とにかく型、型、型

ただ最近盛り上がっている言語というのは何か。さっきの図ですね。

この図で生き残っているFlow、TypeScript、Scala、Elm、Reasonって全部型がある言語なんですよ。ただの型じゃなくて、柔軟な型宣言があるというのが大事で、型推論があること。とにかく型、型、型みたいな。

フロントエンドの事業で、なんでこんなに型が最近重要視されるようになったかと言うと、GUIでテストってとにかく書きづらいですよね。Reactはすごくがんばってサーバーサイドレンダリングでコンポーネントのスナップショット撮ってみたいなことやるんですけど、静的検査で済ませられるんだったらそれに越したことはない。

さっき言ったFluxやObservableは、けっこうデータ構造がImmutableなものを前提としていて、書き換えにシビアにならなきゃいけないという前提があって、そうなると静的検査がないと正直コードを書いていられない。Rxを使う人たちAngularの人たちがよく言うのは、TypeScriptがあるからRxが使えるみたいなことをよく聞きます。

(会場笑)

昔はこういう気持ちでコードを書いていましたよね(笑)。

(会場笑)

あります? 伝わると思うんですけど(笑)。手動テストでポチポチやってた時代。赤が危険な範囲です。「頼む、動いてくれ!」「たぶん動いてるやろ」みたいな感じで苦労してたのが……まあこうなってほしいよねという、これはわりと理想的な姿ですね。

(会場笑)

手動テストは支配的なんだけど、End to End、Unit Test、Static Type Analysisなど、でもここはやっぱり祈りですね。祈りが消えることは絶対にないので。JavaScriptに限らず。カバレッジ100パーセントを目指した世界に何があるかちょっとわからないですけど……あ、これさっきと同じこと言ってるわ。

WebComponentsによってフレームワークは死ぬか

今までFluxや型の話をしてきたんですけど、「じゃあWebComponentsが来たらフレームワークは死ぬのか」みたいな話があるじゃないですか。今はたぶんこうなっていると思うんですよ。

div.root、root要素があって、AppContainerをマウントして、ABC、Button、WidgetA、WidgetB、WidgetCで、Buttonの下にPrimitive Elementがある。というのが、たぶんこうなると思うんですよね。

root要素があって、AppContainerがあってABCがあるのは一緒なんだけど、nodeの末端がWebComponentsになっていく。状態管理層としてのフレームワークは残るんだけど、Viewの末端はCustom Elementsになると思っています。

ただし、そのパラダイムに適した新しいフレームワークも出てくるのは間違いなくて、最近WebComponentsファーストなフレームワークとしてSkateJSがあっておもしろいんですけど。まあReactを使えたら別にいいかなと思っちゃったんですけど(笑)。そういうものとかもあります。

「じゃあWebComponentsが来たら何が死ぬか?」ですが、〇〇デザイン、〇〇実装は全部死にます。マテリアルデザインのReact実装、ViewJSのマテリアルデザイン実装、〇〇フレームワーク集みたいな流れが、みんなNPMから引っ張ってきて使うと思います。

そういうのがWebComponentsの役割としてそちら側に吸収されて、そのnodeの末端としてそれらを使うという感じになると思います。あとデザイントレンドって頻繁に変わるので、そういうものと密に紐付きたくないんですよ。

悪いコードとはモジュール境界が明らかでないコード

いろいろ理想的な話をして高まってきたんですけど(笑)、現場はそうではないと、一度落ち着いて考えましょう。

いろんな立場がありますよね。

僕は1番上のSPA開発者みたいな立場なんですけど、ファンタジーランドの住人が「関数型だ!」、Web標準原理主義者が「NLPMNなんて標準にないもの使ってんじゃねぇ」、あとは「現場はjQueryだからjQuery以外使うなんてあり得ない」みたいな人ですね。

僕らがワーッと、Redux、Reactだ、webpackだ。webpackは死ぬ」と言っている間に「付き合ってらんねぇ」と言ってるほかの言語開発者がいます(笑)。じゃあ我々はどうしたらいいのかと言うと、現場の糞コードをよ。な?

(会場笑)

泥臭いことやるしかないんですね。例えばlintを書く。ESlintを書く。型を書く。グローバル変数を潰す。テストを書く。こんなのみんな耳にタコができてるくらい聞いてきたと思うのでわざわざ言うまでもないと思ってるんですけど。

そもそも良いコード、悪いコードとは何かと言うと、僕はテストがしづらい環境の言語だからこそ静的解析、静的検査ができるというのが大事だと思っていて。

静的検査ができるとコードが捨てられるというのが大事です。コードは捨てるためのもので、動くことも大事なんですけど、それ以上に捨てるパスが用意されているというのが大事です。だから悪いコードというのはモジュール境界が明らかでないコードだと思います。

例えば、これは公開資料でだいたい書いてあることだから言ってもいいと思うんですけど。Qiitaで僕がやったのって、Rails SprocketsをBrowserifyに変えて、グローバル参照渡しをES Modulesに変えて、Backbone.ViewをReactに変えて、ViewとStateをState管理層とView層をきれいに切り離しました。

噂によるとHyperappに置き換えられたらしんですけど(笑)。

(会場笑)

これ別に中の人と喧嘩しているということではなく、けっこう誤解されて外野で騒がれたりしたんですけど、ViewとStateがきれいに切り離されていればそういうのが一瞬できるというのが大事です。

置き換えられるというのは、つまりそういうことです。フレームワークを気軽に変えられるくらいには柔軟。HyperappはJSX記法をそのまま食えるんで。あと中央のState管理層がきれいに切り離されているからこそ、あとの末端はなんとでもなるという話です。

最近freee社でちょっとお手伝いをしてるんですけど、ここでやったのはSprocketsをWebpacker......またSprockets殺してるんですけど(笑)。

(会場笑)

Sprocketsってなかなか手強いんですよね。Railsやっているみなさんに、正規表現で全部書き換えたんですけど、グローバル変数の渡しを変えたり、今Backbone.Routerを1個ずつ解体してたり、あと古いコードにflowの型付けて回ってます。

とりあえずこれやっとけ集で、なにがなんでもこれはやったほうがいいです。

本当に。prettierは最高。eslintのno-unused-vars、未使用変数があったらもうダメ。そのコードは消せる。eslintのprefer-constもimmutabilityが静的に判明してconstかletわかります。付けてください。

大事なのはOSエコシステムに従うこと、Web標準に従うこと、レイヤーを分解すること、それらの土台を確保した上で、全部をぶっ壊すことですね。守っていればより大きなジャンプができる。

そもそもフロントエンドエンジニアとは何か

ここまでいろいろ言ってきて、じゃあフロントエンドエンジニアとはそもそも何なのか? という話だと、僕はフロントエンドエンジニアはこういう。ちょっと面倒くさい図なんですけど、(こういうふうに)理解していて。

普通のtraditionalなWebからWeb Standardの系統と、node.js toolchainの系統があって、node.js toolchainで複雑なことをする合流地点がフロントエンジニアの目線の位置だと思っています。

Server Side node.jsをやってもいいし、Universalという視点で普通のWeb Standardのほうに合流してもいいし、SPA作ってもいいし、ReactNative作ってもいい。あとWebAssemblyを書いてもいい。WebGLも。わりとこれは修羅の道でおすすめです。

(会場笑)

みなさんそれぞれのゴールがあって、スピードのためにフロントエンドをやるという人も多いです。Webフロントエンドってスピードだという人も多いんですけど、継続してコードを発達させるということがそれと同じくらい大事です。

そのためにきれいなコードを書く。捨てられるコードを書く。静的検査で活きるコードを書くというのが僕は大事です。自分がどっちに重きを置いているかというのは意識しながらコードを書いたほうがいいと思います。

フロントエンドアーキテクチャのまとめとして、フロントエンドというもののGUI設計みたいなものと完全に合流したと思っていて、ユニティ、モバイルアプリなど、だからこそReactNativeみたいなものが出てきたんです。ただそれと一緒なのは違って、今のフロントエンドってオブジェクト指向、Functional promming、GUI設計の知見がごった煮で、それらの人たちが主張をぶつけ合うバトルフィールドなんですよ。だから声がでかい人が多くて(笑)。

あなたに必要なのは何ですか? ということで自分に必要なものをうまく見定めて使っていけたらいいですね! というところでこの話は終わりです。お疲れ様でした。

(会場拍手)

続きを読むには会員登録
(無料)が必要です。

会員登録していただくと、すべての記事が制限なく閲覧でき、
著者フォローや記事の保存機能など、便利な機能がご利用いただけます。

無料会員登録

会員の方はこちら

関連タグ:

この記事のスピーカー

  • mizchi

同じログの記事

コミュニティ情報

Brand Topics

Brand Topics

  • 今までとこれからで、エンジニアに求められる「スキル」の違い AI時代のエンジニアの未来と生存戦略のカギとは

人気の記事

新着イベント

ログミーBusinessに
記事掲載しませんか?

イベント・インタビュー・対談 etc.

“編集しない編集”で、
スピーカーの「意図をそのまま」お届け!