MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

Vue.jsを使ってメンテナンスツールを作ってみた

ご無沙汰しております。 マイクロアドでアプリケーションエンジニアをしているNです。

約1年前「JavaScriptフレームワーク(Vue.js)を導入して」というタイトルでブログを執筆させていただきました。
その時、

興味を示して頂き何らかの反応をいただければ、きっと別の社員がもう一歩踏み込んだVue.jsのお話を書いてくれるんじゃないかと期待しています。

と書いたっきり誰も続いてくれなかったので1年越しではありますが、責任持ってアプリケーションエンジニアの N 動きます。

社内メンテナンスツールをつくってみた

最近WEB開発してないんです。 実は去年の4月ころからだいたいバッチしか作らないチームのリーダーにさせていただきまして、それからずっと趣味以外でWEB開発をしてません。
(実は前回のブログを書いた時にはもう。。。)

でもWEB開発したい!JS書きたい。。。

そうだ!バッチのメンテナンスで困っていることをWEBアプリで解決しよう
(基本は自分が楽をするためのツールだけど、他の社員も使ってくれたら嬉しいなぁのノリです)

作成のコンセプト

メンテナンスツールなんで時間を掛けずに作成するを大前提。 凝ったことはなにもしない と心に誓い作りました。

具体的には下記です。

  • トランスパイルしない
  • CSSフレームワークを多用する
  • サーバーサイドは Python & Bottle で実装
  • アツい漢(オトコ)のデータストアはテキストファイル

以下、もう少し具体的にこれらを説明します。

トランスパイルしないで使う

みなさんのトランスパイルの目的はどこにありますか?
わたし個人的には

ES6で書いたけどES6がサポートされていないブラウザでも動作させたいよ

です。 もしそれが目的なら、サポートブラウザを自由に選べる場面では、もはやトランスパイルは不要と考えました。
* よってChromeやFirefoxに絞って使うならES6もだいたいサポートされてるしトランスパイルはなくても良い。
* unittestを行ったりするかもしれないのでmodule bundler(Webpackなど)は検討の余地あり

CSSフレームワークを多用する

複数のフレームワークを使おうという話ではありません。 ある1つのフレームワークを導入して用意されているコンポーネントは極力使って実装しようという話です。 例えば、今回利用したBuefyでは下記のような実装で一覧をサクッと作れます。
多用すれば実装スピードやコードボリュームの削減に大いに貢献してくれます。

Buefy を使ったかんたんな一覧の例
  • HTML
<div id="app" class="container">
  <section>
    <b-table :data="data">
      <template slot-scope="p">
        <b-table-column field="id" label="ID" numeric>{{ p.row.id }}</b-table-column>
        <b-table-column field="f_name" label="First Name">{{ p.row.f_name }}</b-table-column>
        <b-table-column field="l_name" label="Last Name">{{ p.row.l_name }}</b-table-column>
      </template>
    </b-table>
  </section>
</div>
  • JS
const example = {
    data() {
        return {
            data: [
              { 'id': 1, 'f_name': 'Jesse', 'l_name': 'Simmons' },
              { 'id': 2, 'f_name': 'John', 'l_name': 'Jacobs' },
              { 'id': 3, 'f_name': 'Tina', 'l_name': 'Gilbert' }
            ]
        }
    }
}
const app = new Vue(example)
app.$mount('#app')

なんということでしょう。こんなにかんたんに下記のような一覧が作れてしまいます。 Vue.jsはv-modelを採用しているので、dataプロパティの内容を変えてあげれば瞬く間に一覧の内容も変更されます。素晴らしいですね。 f:id:microad-developer:20190815204606p:plain

但し、かゆいところには手が届かないので凝ったUIを思いついても諦める潔さも必要です。

また、独創性を求められるようなサイトでCSSフレームワークを使うと

このUIでは何かの模倣サイトに見える。もっと(独創性のあふれる)使いやすいサイトにしましょう

という話になりがちで、場面によっては不向きと言えるのでお気を付けください。

サーバーサイドは Python & Bottle で実装

この組み合わせが最強ということが言いたいわけではなく、それなりに知識がある言語でシンプルなフレームワークを導入するとスピード感ある実装が出来るんじゃないかという持論です。(RubyならSinatra, JavaならApache CXFなど?) 社内ツールなら極力シンプルにこだわると、あれもこれも出来る強力なフレームワークで「configファイルとの格闘」や「拡張性との妄想」に時間を掛けずに実装できます。(賛否ある面です。単純に個人的見解と捉えてください。)

アツい漢(オトコ)のデータストアはテキストファイル

世界で一番漢(オトコ)らしい選択だと自負します。 今回作ったツールでは遊び心でアクセウカウンターを取り付けたのですが、数値はテキストファイルに保持するようにしました。(アプリの再起動などでカウンタをリセットしたくなかったので) 選定の理由は(ASCII文字を使う限り)世界で一番環境依存しないと思えるデータストアと判断したためです。 実装スピードもその他データストアを利用した場合に比べ約1時間(個人的時間感覚)の短縮が見込めたと思えます。 (RDB的な使い方をしたい場面が出てくるなら絶対におすすめしません。実際この後RDBが必要になりSQLite3に切り替えました。)

結果どれくらい簡単に画面が作れるか

今回の作成のコンセプトに沿った場合、どれくらい簡単に画面が作れるのかをHTML & JSコードだけを特別にお見せしながら簡単に説明させていただこうと思います。

  • HTML
<div id="app" class="container">
  <section>
    <b-table :data="data">
      <template slot-scope="p">
        <b-table-column field="id" label="ID" numeric>{{ p.row.id }}</b-table-column>
        <b-table-column field="f_name" label="First Name">{{ p.row.f_name }}</b-table-column>
        <b-table-column field="l_name" label="Last Name">{{ p.row.l_name }}</b-table-column>
      </template>
    </b-table>
  </section>
</div>
  • JS
const app = new Vue(
{
    data() {
        return {
            data: []
        }
    },
    mounted: function() {
        this.getData();
    },
    methods: {
        getData: function(){
            // axios インスタンスを生成する
            const axiosRequest = axios.create({
                responseType: 'application/json'  
            });
            axiosRequest.get('/api/hoge', {})
                .then(response => {
                    this.data = response.data.list
                    // 下記のようなデータが入ってる
                    // [ { 'id': 1, 'f_name': 'Jesse', 'l_name': 'Simmons' },
                    //   { 'id': 2, 'f_name': 'John', 'l_name': 'Jacobs' }]
                }).catch(err => {
                    console.log('err:', err);
                });
            },
    }
);
app.$mount('#app');

如何でしょうか?
前述のソースコードでデータの取得元をREST APIに変更しただけのコードですが、私が作ったツールも大概一覧画面だったのでほぼこんなソースコードです。 「まだVue.js触ったことないよ!」「CSSフレームワーク使ったことないよ」どちらの方もコードボリュームの少なさに多少驚いて頂けると思われます。

さいごに

こんな感じで、某ツールのAPIやキーバリューストアに保持されたデータを一覧としてチェックする画面をいくつか作ってみました。 いくつかの手順を踏んでやっと表示できる内容も、ブラウザから素早く表示できるので利用者の方々からも大満足のお言葉をいただいております。

今回のお話で多少勘違いされては困るのは「CSSフレームワークは素晴らしい、どんな場面でも使おうよ」と思われてしまったら心外です。
別に使わなくたって「再利用性の高い所はコンポーネント化しておけば同じことだよ。」と思っています。
(Vuexを使った話になると別ですが、Vue.jsのみではコンポーネント間の値の受け渡しは若干面倒なのでやりすぎ注意ではありますが)

Vue.js非常に便利ですね。個人的なお話をさせていただくと、今回のツールを作り益々Vue.js愛が深まりました。

この記事が皆様の社内ツール作成の一役になれば幸いです。
では!良いVue.jsライフ、社内ツール作成ライフを!!