Skip to content

Instantly share code, notes, and snippets.

@yang-wei yang-wei/README.md Secret
Last active Jan 30, 2019

Embed
What would you like to do?
Symfony + Modern JavaScript = Symphony

Symfony + Modern JavaScript = Symphony

概要

  • 管理画面にモーダンのJavaScriptツールを入れて運用している話

管理画面の紹介

commits

  • 2013年からのプロダクト(5年目
  • 広告の入稿、運用、レポート
  • 内部のユーザーだけではなくお客様に公開しているものもある
  • Symfony 2.3 + React.js, jQuery, Vue.js (え?)

チーム

  • ほぼ20人で、全員管理画面触る
  • コード量の一番多いリポジトリ
  • 毎日リリースしている

課題: リッチなUIはカオスなコードになる

1. Symfony Form

magic !

<th>広告タイプ</th>
<td>
    {{ form_widget(form.adType)}}
</td>

<script>
(function(){
// acme_koukoku_new_adTypeはframeworkが生成したid 
$('#acme_koukoku_new_adType').change(function(){
    ...
});
})();
</script>

2. jQueryで頑張りすぎ

$('table#acme tr').each(function () {
    if ($('td:eq(2)', $(this)).is(':contains(停止中)')) {
        $(this).css('background-color', '#cacaca');
    } else {
        $(this).css('background-color', '');
    }
});
$('table#acme').show();
$('div#nowloading').hide();

3. Too many ways to render HTML

// twig
<div>
  {%if user.verified is false %}
   <span>!!!</span>
  {% endif %}}
{{ user.name }}
</div>

// Vue.js
<div>
  <span v-if="user.verified == false"> !!! </span>
  {{ user.name }}
</div>

// jQuery
<div id="user"></div>
if (user.verified) {
  $('#user').text(user.name)
} else {
  $('#user').append("<span>!!!</span>").text(user.name)
}

// React
function User(user) {
  return <div>
    { user.verified ? <span>!!!</span> }
    user.name
  </div>
}

4. 流行りに乗ってない

  • Reactなどのバージョンが古い
  • 参考記事、documentationが古い
  • 流行っているものは実務で使わないから関心がない

進めかた

  • 掃除とバージョンアップ
  • まずは自分で作る(良いよというのを伝えるために
  • 二週間ぐらいかかった

1. 掃除

  • bye bower, hi NPM
  • legacyのライブラリをlegacyのpackage.jsonで管理して新しくpackage.json作って管理するという議論あったけど、一個のpackage.json
  • 既存のライブラリーのバージョンアップ
    • 使っているライブラリー(Griddle)のバージョンが一番新しいReactのバージョン対応してなくてReactを15(当時16が最新)にした
    • Griddleのprでコメントしたら一ヶ月後マージしてくれた
  • コードも新しいバージョンに合わせて
    • Reactのコードはreact-codemod使ってた

codemod

2. DX (Developer Experience)をあげる

  • Webpack + babelを導入して
    • Webpack watchでコード変更時のauto transpile
    • ES6 (async await最強)
    • TypeScript
  • npmコマンドを全部Makefileでラップ
// Makefile
NPM:=yarn
build: test
    $(NPM) run build

build-dev:
    $(NPM) run build:dev

lint:
    $(NPM) run lint
  • ビルドしたファイルはコミットせずデプロイ時にビルドする
  • lint, prettier

3. 方針を決める

  • 画面を作る方法を2個にする
    • 静的な画面、簡単なform: Symfony Form
    • UIのリッチな画面: React
  • Single Page Applicationにしない
  • 全体のリファクタリングはしない
    • 既存の画面で使う必要のあるとき小さくやっていく(ページの一部だけReactを使う)
  • テストできるようにしたけどUIのテストは頑張らない
    • jestのsnapshotテストあまり意味ないなって思う
  • 一つのpackage.jsonでReactと他のUI Framework(例えばVue)を管理するのがむずいからReactだけにした

4. 運用

  • npmパッケージのガーデンにングはrenovate

image

image

  • 監視はnewrelic

image

よかった

  • リッチなUIを作る方法が一つになった(simple)
  • development / productionのJavaScriptを分けれるようになった
  • minifyできるようになった

minify

これからの悩み、課題

  • 画面によってアプリケーションの複雑さは違うからReact使ってもパターンが増える(状態管理のパターン
  • 勉強するコストが増える
  • コード量増えた
  • チーム内での普及

symphony

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.