突然ですが、私は40代です。 最近、弊社のフロントエンドエンジニア募集に興味を持ってくれる若者のスキルの欄に「jQuery」の単語がちらほら見える事が気になっています。フレームワークやらバンドルツールやら便利なものがたくさん存在する昨今、そんな時代に開発をスタートした若者が、なぜ古き良き時代の jQuery???たまたま読んだ記事に私と似たような感覚を持ち合わせた方がいたので、まずはそのURLを紹介させていただきます。

jQueryとは何なのか?なぜ使わなくても(あるいは使わないほうが)いいのか?

上記の記事を読めば何が言いたいのかおおよそ見当が付くと思いますが、加えてチーム開発という観点から私の考えをこの記事にて紹介させていただきます。

開発環境の変化

昔々のお話

その昔、私が初めてWEBページなるものを作った時、ブラウザ相手のアプリケーションってなんて難しいんだろうと思いました。こっちのブラウザで動いたかと思えばあっちのブラウザではエラー、innerHTML やら value やらイベントの target やらこねくり回した挙げ句、アプリケーションのコードはブラウザ判定のための分岐だらけ。そんな時に知ったのが jQuery でした。

どんなブラウザで利用されるかなんて全く気にせず .text() と書けばテキスト表示され .click() でクリックイベントのキャッチも簡単、分岐だらけでグチャグチャだったコードはすっきりシンプル、まさに魔法の jQuery!!HTML ファイルを新しく作れば無意識に手が $(document).ready() をタイピングしている、そんなくらいにどっぷり jQuery の世界に浸っていました。

そして現代へ

それから何年もの年月を経て、ECMAScript は進化し JavaScript の世界でもモジュールやクラスが使えるようになりました。次々とリリースされるフレームワークが便利なデータバインディングを提供してくれ、ちょっと手を伸ばせば TypeScript の型の恩恵に預かることもできます。今やフロントエンドは .html.js ファイルに無秩序に長いコードを書く時代ではなくなったのです。

jQueryを使わなくなった理由

$(document).ready() のシンタックスを忘れてネット検索するほどになってしまった私ですが、それでも jQuery を使う時はあります。それは古いシステムを改修する時や、新規開発であっても大人の事情でどうしても使わねばならない時です。

jQuery は導入が簡単で使い方もシンプル、そして非常に安定したパッケージです。でも私は特別の事情がなければ使いません。それは jQuery が進化したフロントエンドの世界にマッチしなくなった事で「使いづらい」と思うようになったからです。

(1) 依存の問題

例えば jQuery に依存したパッケージ A と B があったとします。A の jQuery のバージョン指定が ~1.0.0 で B が >=2.0.0 の時、1系と2系が競合するため依存が解決できず A と B の両方のパッケージを使う事はできません。 そこで両立はあきらめて A だけ使うとします。今度は自身で開発しているアプリケーションに対して ~1.0.0 の縛りが発生します。jQuery はアプリケーションのどこからアクセスしても同じものを参照をする JavaScript のグローバルオブジェクトに自身の変数を展開するため、複数バージョンが共存する事はできないのです。

~1.0.0 でもアプリケーションの動作上は事足りるからこのバージョンを使えばいいや、と思うかもしれません。でも、新規の機能追加やバグがあった時、古いバージョンのドキュメントを調べたり、フォーラムでそのバージョン固有のバグかどうかを調べるのはとても手間のかかる作業です。私はそんな作業にとてもイラッとします。

(2) 再利用性の問題

jQuery を使ったコードでよく見るのが「DOM の要素に CSS クラスを割り当てて、CSS セレクタでピックアップした要素に対して挙動を持たせる」というものです。この書き方自体に問題があるとは思いませんが、似たようなページやパーツを作る場合に「コードをコピペしてちょっと書き換える」という事をしませんか?もしくはそれを嫌って関数などで処理を共通化した場合、ちょっとした挙動の違いをフラグなどで分岐させて対応しようとしませんか?

開発している時はさほどストレスを感じないこの作業、首を絞めるのは仕様変更の時です。ほんの少し挙動が変わるだけでもあちこち検索して大量にコピペを繰り返す必要があります。それと同時に怖いのはコードの変更の影響範囲が見えづらいという事です。 <div class="A"><input class="A B"> があった場合 $('.A') に対する変更は $('.B') に対して影響しませんか? $(targetClassName).click() なんてコードが実は $('.A') をターゲットにするものだったとしたら、テキスト検索だけでは足りずコードを読まないと仕様変更の対象かどうか判断付かないですよね。

DOMの要素や挙動を別の場所でも使えるようにする事を「再利用性」といいます。(jQuery を使ったすべてのコードがそうだとは言いませんが)簡単に DOM に挙動を追加できる便利さゆえ、それだけに頼るとコピペの多用で再利用性の低いコードになりがちです。

(3) テスタビリティの問題

その昔、私が jQuery をふんだんに開発に使っていた頃は「テスト」という習慣はありませんでした。ツールやページごとに開発担当者が割り当てられ、自分で変更したコードは自ら動作確認をしバグを出したら自己責任で修正していました。それに比べ最近では、モダンな開発を謳っている会社ではそのほとんどがテストを書くことを習慣づけていると思います。

テストを書くという事はプロダクションコードに加えてテストコードも書くという事で、コードのボリュームが増大するのに加えテストを書く技術力も求められます。それでもテストを書くことには大きなメリットがあるのです。

WEBページを作る場合、テストがなければコードを書き換えながら何十回もブラウザのリロードを繰り返すでしょう。例えばユーザーの入力に応じてデータ検索をするページを考えると、正常な検索テキストが入力されるケース、何も入力せず検索されるケース、バックエンドの API レスポンスが HTTP 403を返すケース…と何通りもの動作確認が必要になります。

仮に HTTP 403のレスポンスを受け取った場合に「処理は中断するがエラーメッセージは表示しない」という仕様だったとして、それを自分以外の開発者に伝えるためにどうしますか?コードにコメントで残したり、動作確認手順書を作ったり、いろんな方法があると思います。でもそんな事よりもテストに書いたほうがずっとシンプルで簡単です。仕様を把握しきれていない仲間の開発者が「エラーメッセージが表示されない、バグだ!!」と勘違いして挙動を変更した場合、テストが落ちる事で何か破壊した事に気づけるのです。

それに加え、テストは何十回ものブラウザのリロードからも解放してくれます。先に述べたいろんなケースは全部テストに書いておけば良く、これも同じように挙動を変更した時にテストが落ちれば何か破壊した事に気づく事ができます。

前置きがとても長くなりましたが、jQuery でボリュームたっぷりに書かれたコードで十分にテストされているアプリケーションを私はほとんど見たことがありません。私なりに推測すると、GET リクエストで WEB ページ全体を取得してから対象の要素をピックアップし、何らかのアクションを実行、結果が表示された要素をまたピックアップし…と、とにかくテストの手順が多くて大変なんじゃないかと思います。そして手順の多いテストは仕様変更の影響を全面的に受けてしまい、HTMLのちょっとしたレイアウト変更が入るだけでプロダクションコードと共にテストコードもあちこち修正する羽目になるでしょう。

先に述べた再利用性の低さはテスタビリティにも大きく影響します。再利用性の高いコードほど、テストは手順が簡単で仕様変更の影響を受けにくくなります。そしてテスタビリティの高さは、チーム開発に大きく影響します。

(4) 設計の問題

アプリケーションを開発する上での設計ってなんでしょうか?私はあんまり上手に設計できる人ではないので自信を持って言えませんが「読みやすく、仕様変更に強く、他の開発者と作業分担しやすい仕組みは何か、悩み考えそれをコードで表現する事」じゃないかと思います。

先人達の知恵、デザインパターンやMVCアーキテクチャなんて言葉を聞いた事はありませんか?こういったものを勉強して jQuery で書いた長いコードに取り入れようとするのは至難の業です。それは jQuery がいかに簡単に DOM を操作できるかをコンセプトにしたパッケージで、アプリケーションの設計のためのものではないからです。中には jQuery を駆使しつつ熟慮された設計のアプリケーションもあるでしょう。ただそれとは逆に、簡単に DOM を操作できるがゆえに実装スピード優先の楽なコードに逃げがちになってしまうのも事実だと思います。

良い設計のアプリケーションはコードが適度に分割されていて、テストも書きやすくなります。もちろん設計には失敗もありますが、また次に新たなエッセンスを取り入れて「この部分はうまく設計できたかも!」と思えるのは開発者の醍醐味ではないかと思っています。

フロントエンドエンジニアの仕事は、静的な WEB ページに JavaScript で動きを付ける事ではありません。バックエンドエンジニアと同じように、資産として残る「良いコード」を模索して実現していく事が大事な仕事だと思うのです。

脱jQueryのはじめの一歩

見直してみよう

jQuery を使ったコードに限った事ではありませんが、完成したアプリケーションをよく見てみてください。

  • そのコード、テストは書けていますか?
  • 仕様変更の影響が小さくなるように考えられていますか?
  • HTML のレイアウト変更で大ダメージを受けたりしませんか?
  • 誰かに作業をバトンタッチする場合にコードで仕様が伝わりますか?

見直した結果がダメダメだったら…

設計ってどこから手を付けて学んだら良いのでしょうか?

個人的にはフレームワークを学ぶのが一番の近道なんじゃないかと思っています。フロントエンドの世界にもいろんなフレームワークがあり、それぞれにコンセプトがあり設計のエッセンスが詰まっています。

「フロントエンド フレームワーク」で検索すればどんなものがあるか簡単に見つかるでしょう。聞いたことがある、ロゴが好き、GitHubのスターが多い…などなど、最初のきっかけは何でも良いと思うので是非どれかひとつ使ってみてください。公式ドキュメントのスタートガイドを読めば、だいたい10分足らずで最初の “Hello World!” が表示できるはずです。

もちろんフレームワークには難しさの面もあり、使い方が分からなかったり、固有のバグに悩んだりもして jQuery の世界に帰りたくなるでしょう。でもそこでめげずに、どんなに小さいものでもいいのでひとつアプリケーションを作ってみてください。再利用性とテスタビリティがぐんと上がって、長いコードを書いていた頃よりも開発がずっと楽になります。

私がはじめて使ったフレームワークは AngularJS で、今は Angular を使っています。使い始めの最初の頃は、フレームワークの特定の機能が思うように動いてくれなくて何時間も調べてばかり、今日は数行しか書けなかった、なんて事もよくありました。でも設計のエッセンスを知る事は楽しいし、とりあえず動かすためのちょっとトリッキーなコードを書いて逃げるよりもフレームワークで提供される機能をきちんと理解して使うほうが自分にとってベストプラクティスだと思っています。

Angular はネット上では「敷居が高い」とか「なんか難しくてやめた」なんてコメントが散見されますが、私自身はそんな印象はなく学びが多く良いフレームワークだと思っています。処理はどこで共通化し再利用するのか、コンポーネントって何なのか、コンポーネント同士はどうやってデータをやり取りするべきなのか、ロードするタイミングをどのようにコントロールするのか、凄腕の開発者の人達が考えた設計が Angular の書き方のお作法として詰まっているため、それを学ぶ事で設計のヒントを得てコーディングの引き出しを増やす事ができるのです。そのヒントや引き出しは Angular を使わないアプリケーションを作ったとしても、とても役立つものです。

おわりに

この記事のタイトルをなぜ若者への呼びかけにしたかと言うと、これから先の長い期間、設計に苦しみ悶々と悩み「良いアプリケーションとは何か」を考える事ができるからです。私ももちろん日々設計と向き合って悩んでいますが、私より若いみなさんにはもっともっと悩んで勉強して成長していって欲しいと思うのです。

jQuery はフロントエンドの世界を切り開いてくれた素晴らしいパッケージです。今までさんざんお世話になった jQuery に感謝を込めつつ、フロントエンドエンジニアを目指す若者たちにもう一度問いかけたいと思います。

「脱 jQuery」してみませんか?