ES6で始めるjavascriptリファクタ
javascript ecmascript

ES6で始めるjavascriptリファクタ

このエントリーをはてなブックマークに追加

こんにちは、コンテンツ事業部の井田です。

さて、今回はjavascriptに関連する投稿です。

弊社でもここ1年ほどでjavascriptの最新技術の取り入れが盛んになってきました。 しかし、数年間続くシステムだと最新どころかスパゲッティ化してしまって動いているけど手を入れづらいことがあるかと思います。

往々にして数年前の自分がやらかしてたりするんですが…

数カ月前にこういった状況に実際に直面し、思い切ってES6の構文を取り入れつつリファクタを実施してみました。 今回はその実施内容のご紹介です。

※リファクタに際しbabel,gulpなどのツールを用いましたが今回はその導入手順は省略させていただきます。

##Before

まずは実施前のコードの構造がどうだったかを簡単に。

<div>......</div>
<script>
$(function() {
  $.ajax({//機能Aに関するデータ取得
    success: function(data) {
      //機能Aのレンダリング・イベント処理
    },
    ...
  })
});
</script><div>......</div>
<script>
//機能Bの表示非表示制御など
</script>

困ったことに突貫工事を繰り返した結果以下の様な問題がありました。

  • 同一HTMLに複数機能のHTMLとそのインラインscriptが存在
  • 1機能に対しscriptがheadにもbodyにも存在するといったことも
  • jQuery.Deferredなどを使わない深いネストとなった非同期処理
  • 全ての処理が1つのコールバックfunction内に記述
  • この構造が計5つ、1つのHTMLに存在

さて、これまでは各々の機能が独立して稼働していたのでそっと蓋をしておいたのですが、この構造の中でAがONのときはBをOFFにしたいといった機能同士が絡み合う実装が必要になってしまい、リファクタをするに至りました。

##やったこと ###クラス/function分割

まずは機能ごとでjsファイルを分割することにしました。 それに伴い、以下のように処理もメソッドに分割し、 また、メソッド名の規則を定めることでより見通しを良くしました。 以下がそのテンプレートサンプルです。

//samplea.js
export class SampleA {
    constructor() {/*初期化*/}
    render() {/*DOMの書き換え*/}
    api() {/*API実行*/}
    onClick() {/*イベントリスナー*/}
    show() {/*この機能を表示する*/}
    hide() {/*この機能を非表示する*/}
}
export default new SampleA();

これにより以下のよう機能間の出し分けなども簡単になりました。

//index.js
import A from "./SampleA"
import B from "./SampleB"
let target;
if (機能実施条件) {
  target = A;
} else {
  target = B;
}
target.show();

オブジェクトではなくクラスにしたことで以下のメリットがありました。

  • 他言語のエンジニアでも理解しやすい
  • 再利用性

###Promise化 いままでコールバックで実行していたものを、以下のようにPromise化します。

api() {
  let promise = Promise.resolve($.ajax({...}));
  promise.then(this.success, this.error);
  return promise;
}
success(data) {/*API結果の処理*/}

setTimeoutも以下のように

timeout(sec) {
  return new Promise((resolve, reject) => {
    setTimeout(resolve, sec);
  });
}

これで非同期処理の深いネストも解消され見通しが良くなりました。

###ESLintによる構文チェック ESLintを用いコードフォーマットを統一を図ります。 以下は今回実施した設定の一部です。

"indent": ["error", 4],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "single"],
"semi": ["error", "always"],
"comma-spacing": ["error", {"before": false, "after": true}],
  • インデントはスペースx4
  • 改行コードはUNIX
  • 文字列はシングルクォートで囲う
  • 行末のセミコロン必須
  • カンマの「後」にスペースを空ける など

まずはエラーとなるような設定で細かく実施し、徹底的に統一しました。

以上が今回やってみたリファクタの概要です。 今回出てきた構文以外にも様々な構文があり、javascriptを綺麗に・簡単に・わかりやすく書くことが出来るようになっています。 みなさまもぜひ、ES6に思い切って変えてみてはいかがでしょうか。


名無しのエンジニア
GMOテクノロジーブートキャンプでMySQLおじさんしてきた
Treasure Data に蓄積した行動履歴から決定木を使ってユーザの継続要因を調べる