読者です 読者をやめる 読者になる 読者になる

Opt Technologies Magazine

オプトテクノロジーズ 公式Webマガジン

オプトテクノロジーズで使われているフロントエンド技術

JavaScript プロダクト React.js Angular.js

alt

こんにちは、4月よりオプトにjoinした@_sisisinです。
主にフロントエンドエンジニアとして業務に携わっております、以後お見知り置きを。
さて今回はオプトで現在使っているフロントエンド技術について、私の関わっているプロダクトを中心に紹介しようと思います。

近年のフロントエンド環境について

フロントエンド開発で利用される技術は、直接プロダクションコードを書くためのライブラリなどに留まらず、多岐にわたっております。
オプトで利用している技術を紹介する前に、それらのフロントエンド環境について簡単におさらいしていこうと思います。

様々なフロントエンド開発の技術をざっくりジャンルで振り分けると下記のようになるかなと思います。

  • framework/library
  • package manager
  • AltJS/AltCSS
  • module bundler
  • lint tool
  • test tool
  • task runner

ではこれらについて簡単に説明していこうと思います。

framework/library

はい、括りがすごい大きいですね。
フロントエンド(というかJavaScript界隈)では本当に小さな機能もライブラリを利用する文化があり、簡単にジャンル分け出来るような領域ではないのでこのぐらいでまとめてしまいました。

ここでよく話題になるのはMV*系やFlux系のフレームワーク・ライブラリ群ですね。
AngularJS,Vue.js,Redux,Reactなど、聞いたことがある方も多いと思います。
これらのような基盤に関わるもの以外にも、イミュータブルな集合操作を行えるImmutable.js,グラフ描画を担うD3.js,定番DOM操作ライブラリjQueryなどなど、様々なライブラリがあります。
これらの道具を使ってプロダクトを作っていきます。

package manager

さて、読者の皆さんはJavaScriptのライブラリ群をどのようにして管理しているでしょうか。

JavaScriptのライブラリの取り扱いは、公式サイトで配布されているzipを落としてきてローカルで保存やCDNの利用など、これまで色々な方法が模索されてきました。
そしてNode.jsの登場に伴い、パッケージマネージャnpmが生まれました。
それからbowerやjspmなどのフロントエンドに特化したパッケージマネージャが生まれたり、他にも流行り廃りありましたが、現在はnpmにて一元管理する方針が多く見受けられます。
npmの公式ブログ記事でも、npmに一元化しようという提案がなされていることからもその動きが伺えますね。

AltJS/AltCSS

AltJS/AltCSSとは、それぞれ変換(transpile)してJavaScript、CSSになる言語のことです。
例えばTypeScriptやElmといった言語などが挙げられます。
また、ESnextの記法で記述されたコードをES5の文法にトランスパイルするという方法も一般的に行われていて、実質AltJSと同等の扱いをされています。

JavaScriptの言語機能に満足できなかったり、jsの新しい機能を先取りしたいときにこれらを利用して開発していきます。
先日TypeScriptの2.0betaが出てきたばかりだったり、BabelもESnextへの対応を随時進めていたりと活発な領域ですね。

module bundler

CommonJSスタイルで管理されたモジュールの依存関係を解決し、モジュールの概念をフロントエンドで利用できるようにしたツール、それがmodule bundlerです。
モジュールの概念のない荒野に舞い降りたフロントエンドの救世主といえるでしょう(js世界の複雑化を推進した悪魔という話もある)
具体的にはbrowserify,webpackなどですね。

主な仕事としてrequireで参照したファイルの依存関係を解釈し、1つのファイルにまとめてくれます。
これによって、フロントエンドのコードをモジュール単位で記述し、小さいスコープでコーディングがしやすくなりました。

es2015 modulesが策定され、これを利用しなくてもモジュール単位でのコーディングが出来る世界が見えてもきましたが、
まだ各プラットフォームで実装されていない上に、仕様についても議論の過程にあります。 この辺りの話は、Node.js 日本ユーザーグループ代表の@yosuke_furukawaさんのブログ記事に詳しく書かれています。 以上のように、JavaScriptのmodule環境は過渡期と言えるため、まだまだmodule bundlerのお世話になるのではないかと思います。

lint tool

プロジェクト全体でコーディングスタイルが統一されているのは気持ちいいですよね!lintはそんな気持ちを支援してくれます。
静的解析をして、設定値に従ったコーディングスタイルかチェックしてくれるありがたいツールです。

jshintやeslintのようにjavascriptをlintしてくれるツール以外にも、typescript用のtslintなどもあります。
エディタ連携も出来て、コーディングをしながらその場で注意してもらえるようにも出来ます。

test tool

ユニットテストに関連するツール類です。
下記のような分類のものが該当しますね。

  • テストランナー(mocha,karma)
  • アサーションライブラリ(power-assert,chai)
  • モックライブラリ(sinon,jsdom)
  • カバレッジ計測(istanbul)

テスト回りはプロジェクトの利用しているFW/ライブラリ、テストしたい範囲など、状況に応じて様々な構成になるため一筋縄ではいかないところです。
テストツールの選定や構築で苦労しないよう、なるべくDOMに依存しないなど、ユニバーサル(=実行環境を問わない)でテスタブルなコードを書くというのが開発を楽に進める一つの手なのかもしれません。

task runner

ここまで多様なツールを紹介してきましたが、これらの作業を一つ一つ開発中に行うのはそこそこコストが掛かってしまいます。
開発時にソースコードを変更するたびにtranspileしてtest走らせてlintチェックして・・・など毎回実施していたのではコーディングもままならないですし、
本番環境へのリリース用ビルドでは出力するファイルの難読化を行いたいなど、やるべきことが意外と多いです。
これらの作業をまとめあげ、実行してくれるのがタスクランナーの役割です。

ここ最近はnpm scriptで良いのでは?という声も多くありますが、依然としてgulpが根強い人気を集めていると思います。
また、module bundlerの項で紹介したwebpackもconfigの設定次第でgulpに近いことが出来るため、こちらに移行している人も多いようです。

使いドコロを間違わなければ開発を強力に支援してくれるツールですね。

--

簡単にと言いつつ盛りだくさんでしたが、いかがでしたでしょうか。
これだけ多様な技術を組み合わせていかなければならないというだけでフロントエンド開発のカオスっぷりが伺えますね!

オプトでもこれらの技術をその時その時で取捨選択しつつ開発をしております。
ここからはその組み合わせをいくつか紹介して行こうと思います。

オプトで採用してるフロントエンド環境

ここからはオプトの実プロダクトの構成についての紹介に入っていこうと思います。

オプトのフロントエンド case1

  • framework/library
    • AngularJS(ver 1.4)
    • Immutable.js
  • package manager
    • npm
    • bower
  • AltJS/AltCSS
    • TypeScript
    • sass
    • stylus
  • module bundler
    • なし
  • lint tool
    • tslint
  • test tool
    • なし
  • task runner
    • gulp

いわゆる管理画面系のフロントをこんな構成で作っております。
AngularJSを中心に据え、その回りのツール類はザ・Angularな構成になっております。
npmではタスクランナーのパッケージのみを管理しており、bowerにてフロントで利用するライブラリを管理。
画面上ではscriptタグでbower_componentsを読み込み、プロダクトコードはTypeScriptを--target es5でトランスパイルした結果をconcatで1ファイルに結合というわかりやすい構成ですね(* これがわかりやすいというのはフロントエンドに毒された人間の言説です!!!)

ユニットテストがない(!)ですが、現在進行形で環境の構築など、導入の準備を進めているところです。
他にも課題としてTSのトランスパイル時間が遅くなってきている(最大25s程度)ので、解決できないか調査しているところです。

このプロダクトは比較的オーソドックスなAngular構成で、TypeScriptによる型の恩恵もあるおかげで大規模でありながらも開発しやすい構成になってると感じています。

オプトのフロントエンド case2

  • framework/library
    • なし
  • package manager
    • npm
  • AltJS/AltCSS
    • TypeScript
    • CoffeeScript
  • module bundler
    • browserify
  • lint tool
    • tslint
  • test tool
    • mocha
    • selenium-webdriver
  • task runner
    • gulp

こちらはcase1とは打って変わって画面のないフロントエンドです(!?)
GoogleAnalyticsのタグなどと同じ、埋め込みタグの実装なのでフレームワークなどの利用はしておりません。
プロダクションコードをTypeScriptで書き、ユニットテストをCoffeeScriptで記述という形をとっています。
また、通常のユニットテストに加えてブラウザテストも行っております。
こちらはnodeでモックサーバを立てながらtranspile->bundleして吐き出されたコードをselenium-webdriverを用いてテストを実行し、実際にタグを埋め込んだ際の挙動もチェック出来る仕組みを作っています。

TypeScriptの型の恩恵に加え、testとlintも完備されている盤石な体制ですね。
GUI(=DOM)の層が薄いという特徴を活かした構築になっていると思います。

オプトのフロントエンド case3

  • framework/library
    • React/Redux
    • lodash
    • axios
  • package manager
    • npm
  • AltJS/AltCSS
    • ES2015
    • sass
  • module bundler
    • webpack
  • lint tool
    • eslint
  • test tool
    • mocha
      • chai(expectを利用)
  • task runner
    • npm script

こちらもまた管理画面系ですが、今度はReactになっています。
一部でウェイ系スタックなんて言われてる感じの構成になっていますね!
バックエンドはRailsなのですが、Sprocketsには依存させずにnpmのエコシステムのみで動くように構築されています。
また、リポジトリもバックエンドとフロントエンドで分けて作っており、フロント/バックエンドで分業して開発が進んでいます。

AltJSはメンバーのスキルセット及び構築上の手間を鑑みてES2015をBabelでトランスパイルする形をとっております。

テストについては主にjsのロジック部分はテストを書くようにしております。
ReactComponentはテストを書いておりませんが、リリース優先という判断のもとそうしています。

課題としてユニットテストがまだ導入されて間もないので、もっとテストを充実させなければならないという点が挙げられます。

case1、2と違ってTypeScriptを利用していない分、型の恩恵は受けられていないですが、ライブラリを多用する構成で発生しがちな型定義ファイルで苦労するということがないので、その点においてはスムーズに開発を進めやすいと思います。
また、サーバサイドがRailsのプロジェクトでありがちな、フロントがnpmで完結しなくて辛い問題へも対処されていて開発に集中しやすいのが良いところですね!

まとめ

オプトのフロントエンド、いかがでしたでしょうか。
画面系のUTが課題になっていますが、全体的に時代に応じてベターな構築を出来ているのではないかと思っております!

今後の展望として、npm/TypeScript/webpackのスタックにFWを適宜組み合わせるような構築でやっていければと考えております。
直近では下記の2つをやっていきたいですね。

  • ReactとTypeScriptの組み合わせでコンポーネントのテストの導入
  • Angular2を試しつつ1系のプロダクトのアップデートの道を模索

今回は紹介と展望について触りだけの紹介に留めましたが、より掘り下げた記事も書いていきますので乞うご期待!

最後に

オプトではフロントエンドのエンジニアを募集しております!
SPAの開発をバリバリやってみたいという方や、オプトテクノロジーズに興味があるという方はこちらの採用ページからご応募ください!