編集者が最近のフロントエンド技術に初挑戦して仕事用アプリを作ったので見て

つくったもの

原稿の締切と進捗を管理するシステムです。

f:id:slideglide:20171206223410j:plain

これが画面の全体像のキャプチャです。モザイクが多くてよくわからないので、ちょっと説明を加えたのが下の画像です。

f:id:slideglide:20171206223454j:plain

上のほうに、その日と翌日の掲載予定記事が出ます。その下にカードのような感じで表示されているのが、各原稿の締切/進捗管理です。

f:id:slideglide:20171206223450j:plain

カードは締め切り日順に表示されていて、各カードの内容はこんな感じになっています。締め切りを本人に伝えたかどうかとか、ネタのメモを書き込むことができます。ステータスは未入稿・チェック中・リライト中・入稿済みの4種類があり、手で更新します。
この日は三土さんの締切で、まだ原稿が入稿されていないことがわかりますね。(三土さん晒してすいません。この記事は無事掲載されました
締切1週間前とか、超過とか、状況によってカード自体の色も変わって気づきやすくなっています。

背景

僕はデイリーポータルZ(以下、DPZ)というサイトで編集者をしています。実はDPZはレギュラーライターが常時40〜50人いる大所帯で、そのうち15人ほどを担当しています。これが7〜8人だと自分の脳内RAMに収まるのですが、15人ぶんの進行管理を並行してやっていくと容量が足りないんですよね。それで「すみません、締切遅れます!」みたいなIMを受け取って初めて「はっ、今日か!」みたいな感じになる。軽い感じで書いてますが運営責任のある側の立場の人間として普通にやばい状況ですよね。そこで締切管理をシステム化することにしました。

解決したい問題

DPZの原稿の締切は、ぜんぶGoogle Calendarで管理しています。スケジュールのパターンが何種類かあり(不定期の掲載日が決まってて逆算で締切が決まる人、定期的な締切がある人など)、このパターンにより個人カレンダーだったり共有カレンダーだったりと保存先が分散しています。同時に見ることはできますが書式がバラバラですし、担当外のライターの情報もモリモリ入っているので、必要な情報を見落としやすいんですね。

f:id:slideglide:20171206223437j:plain
この中の1/3があなたの担当だから目視で探してね、という状況です

なのでこれを
・複数カレンダーの締切予定を一元管理したうえで
・自分の担当だけ見る
というのが目標です。

技術的背景

一応、僕のスキルもご説明しておきます。編集者といってもずぶのプログラミング素人というわけではなくて、嗜む程度にはできます。たとえばパソコンにダジャレを考えさせた*1マイコン使ってメガネを発射することができます*2

f:id:slideglide:20171206225245p:plain
パソコンがキャバクラ幕府を再発明した瞬間

http://portal.nifty.com/2016/07/26/a/img/pc/c.gif
撃てるメガネ

あとDPZでもCMSのテンプレートは書いているし、編集部内では僕が作った効率化ツールがいくつか使われています。ただすべて独学なのでコードの良し悪しとかはよくわからないし、スキル的にもオブジェクト指向も使いこなせていないレベルです。

Webの知識に関しても10年前のjQueryとかprototype.jsの時代で止まっているので、この機会にモダンなものにちょっと触れてみることにしました。

何で作るか(フロントエンドは地獄説)

さて作りたいものが決まったので、どうやって作るかを考えましょう。今覚えるべきフロントエンド技術はコレ!みたいな記事を読むと、リアクト?とかサース?とかローダッシュ?ククレ?ゴールデン?こくまろ?みたいなのが100万個くらい並んでて、あまりの多さに「こんなに覚えなきゃいけないフロントエンド開発はクソ!」みたいなコメントがついてるのが定番じゃないですか。僕もこれまでは「なんなのこれ…」と思ってたクチでしたが、せっかくなので今回取り入れられそうなものは全部覚えることにしました。

f:id:slideglide:20171207002930p:plain
今回使う(=勉強する)技術要素のイメージ

上の図、ブラウザは別として、今回使いそうなものだけで8個ありました。ぜんぶ今まで使ったことないやつ。8個。8個かー…。

光 プレート 締切CLOSED PL64-3

光 プレート 締切CLOSED PL64-3

余談ですが締切はAmazonでも買えます

まず触ってみる

いきなり作り始めるには何もかもわからなすぎなので、とりあえずそれぞれの技術要素についてちょっとずつ触ってみることにしました。(他人に説明できる立場ではないですが、いちおう固有名詞には注釈を入れておきます。)

1. エディタの準備(Visual Studio Code)

そこからか、という声が聞こえてきそうですが、そこからです。普段サクラエディタを使っているのですが(Vimも一応触れますが常に挿入モードにしてメモ帳ライクに使うという腐れ外道です)、モダンなエディタも触ってみることにしました。評判がよさそうなのでVS Code*3にします。
……快適でした。貼り付け時のインデントが勝手に整形されて楽!階層で折りたたみできて便利!拡張子ごとの色分けが豊富!!!(まだ使い込んでないのでそのくらいしかわからないけど…)

2.開発環境構築(nginx、node.js、webpack)

Webサーバはとりあえず自宅のwin10機にnginx*4を入れて、ローカルからだけアクセスできるように設定しました。自分用ツールだしこれでいいや。
次にnode.js*5を入れます。インストーラ実行するだけなので超楽ですね。とりあえずwebpackを動かすために入れただけなので、まだコードは書きません。
で、次にwebpack*6。インストールしました。インストールはできましたが、これBootstrap*7どうやって導入するの?Webの情報見て入れたらなんかエラー出るようになったけど??あとこれbodyタグの末尾にjs入れたいときどうするの???つうかそのやり方がそもそも古いの????

ここでつまづいてしまい、環境構築にまる2日かけても終わりませんでした(といっても子供が寝たあとの数時間×2ですが)。いつになったらアプリケーション書けるんだよ、としびれを切らして結局webpackは諦めました。あとで使おうと思っていたSass*8も自動的にやめになりました。また来世!

3.S・P・A!S・P・A!(Vue.js)

今回はフロントエンドの技術に触れることが主目的なので、SPA*9とかいうやつをやってみることにしました。
フレームワークはVue.js*10を選びました。小規模開発に向いてるらしいので。あと語感がいい。ヴュー。

4.かっこいいページにしたい(Bootstrap)

先ほど「編集部内では僕が作った効率化ツールがいくつか使われています」と書きましたが、こういう画面です。

f:id:slideglide:20171206223445j:plain

酷い。今回はBootstrap*11を使ってちょっとマシな感じにしたいと思います。

5.外部サービスとの連携(Google Calendar API

カレンダーの一元管理&フィルタリングが目的なので、API経由でのカレンダーとのやり取りは必須です。
本家のチュートリアルがあったので基本的な使い方はわかりましたが、ネット上にあんまり作例が見つけられなかったのでちょっと心細いです。最初に試したのは以上です。

6.そういえば…

図には入れていたMongoDBの事に触れてませんが、試すのすっかり忘れてました…。

高級感のあるステンレスの締切です

実装

イカレたメンバーがそろったところで、いよいよ実装に入ります。完成までの様子を順を追って見てください。

フェーズ1:カレンダーの取得

f:id:slideglide:20171207235851j:plain

やったこと
Google APIで予定を取得

これは簡単でした。なぜならチュートリアルほぼそのままだから。

フェーズ2:Vue.jsを使って予定を表示

f:id:slideglide:20171206223423j:plain

やったこと
この記事にあったTodoリスト管理をコピペして改変、取得したカレンダーを表示

ここで非同期通信の取り扱いがよくわからず2日はまりましたが、async/await*12という神のテクノロジに出会うことにより解決しました。
ここまででトータル5日ほどかかっています。当初ははりきって着手したものの、些細な問題で数時間悩むようなことが重なり、もうすでにかなりやめたくなっています。でもやめると締切を忘れてやばいので頑張りました。後がない状況は人間を成長させます。

フェーズ3:締切一覧を実装

f:id:slideglide:20171206223415j:plain
※さっきとあんまり見た目変わってないけどデータの中身が違う

やったこと
・config.jsという設定ファイルを作って、担当ライターの情報を記入。(あとでどこかに移動したい)

・データ構造を整理。カレンダーの予定をもとに、必要な情報をハッシュにして締切リストとして管理するように。その際に担当外のライターの締切は除外するように。

・複数のカレンダーの情報を取得、マージできるようにする。

・それなりに表示できるようになってきたので色を付けたりする。

・1週間以内の締め切りは色が変わるとか、そういう細かいUIの実装

一度は嫌になったものの、その後はちょっと要領がつかめてきたので比較的スムーズに進みました。
この時点で、一応それなりの機能を持ったアプリケーションが完成しています。締切をカレンダーから取得して一覧表示する、締切ビューワです。当初の「締切を見やすく」という目的はすでに達成できたといってもいいでしょう。しかしこうなってくると欲が出て、もうちょっと便利にしたくなりますね。

フェーズ4:メタ情報の実装

f:id:slideglide:20171206223410j:plain

Googleカレンダーで管理している情報は、締切と掲載日とライター名だけです。実際に進行管理していく上ではそれ以外にも必要な情報があります。例えば次回の締め切りを本人に伝えたかどうかとか、企画の内容とか、原稿が入稿済みかどうかとか、そういうステータス情報やメタ情報があるわけですね。せっかくなので一緒に管理したい。

このへんは当初はnode.jsとMongoDB*13を使ってサーバ側に保存する予定でしたが、新しいことを覚えすぎてそろそろ疲れてきました。重い腰が上がらずぼんやりGoogle Calendar APIのドキュメントを眺めていると、そこには予定ごとにdescriptionというテキスト項目が。これでいいじゃん、と思ってここにメタデータを突っ込むことにしました。

f:id:slideglide:20171207013015p:plain
Google Calendarの画面から見たところ。SQLインジェクションテストの跡っぽい

後で思ったけどセミコロン区切りとかじゃなくてJSONにすべきですねここは。

やったこと
・View層、Viewmodel層ともにメタ情報の枠を作る

・メタ情報を入力したらGoogle Calendarを更新する処理を実装

こうやって細かい機能実装していっても、Vue.jsのおかげでイベントでがんじがらめにならなくて最高。

・せっかくカレンダーにアクセスしてるので、ついでに今日の掲載予定記事とかを出す

結局、このアプリケーションはwebページ1枚で完結しました。現在のところサーバ側ロジックが存在しません。正真正銘のSPA(?)。

f:id:slideglide:20171207003013p:plain
半分しか使わなかったな……

現在はここまでできている状態です。自分用としてはかなり実用的なシステムになったと思います!
作業工数的には10余暇人日(子供が寝てからの余暇時間をすべて投入×10日分)くらいでしょうか。作ったものはGithubにあげてあります。使い方がわからず、何も修正してないのに5回もCommitしてしまいました……。
独学のためコードの良し悪しがわからないので、お気づきの点があればお知らせください。

フェーズ5:複数ユーザ対応

同僚に少し見せたところ自分も使いたいという声があったので、今後は複数ユーザ対応を行う予定です。

やること
・ローカルのnginxで動いているのをクラウドサーバに移す

・使う人が変わるとGoogleアカウントが変わるので、認証情報の管理が必要

上記の認証情報含めた各種設定(いまはjsファイルで置いてある)を、UIで設定できるようにしてサーバ側に保存するか、ブラウザのWebStorage*14に移した方がよさそう。前者だとついにサーバ側ロジック書かないといけない。後者は楽だけどPC変わると再設定になるので不便。

そこまでできるかどうかわからないけど、当面の目標としてはそんな感じです。

木目調のおしゃれな締切です

感想

ほんのさわりだけですが、モダンな開発環境に触れた感想です。

  • VS Codeはこれから常用しよう
  • async/awaitやばい。革命。あとfor...ofもやばい。Javascriptが全体に昔よりずいぶん便利になってる
  • もうvarじゃなくてconst/letの時代だということにあとで気付いたけど面倒だったので直してない
  • Vue.jsよい。自分が作る程度の小さいものはフレームワーク使うほどでもないだろ、と思ってたけど、小さいものでも導入する価値がありそう。
  • Bootstrapを使ったら即あかぬけたページになるのかと思ってたけど全然そんなことなかった。結局デザイン力は必要
  • webpackとSass、node.jsは今後のTodo

ほかに今後やってみたいこととしては、
・Gitでのバージョン管理(ドキュメントを読めば理屈はわかるけど運用のイメージがわかない)
・テストコードを書く(もう誰かに教えてもらわないと一生わからない気がする)
です。

感想2

こういう感じで、僕みたいにスキル的には弱くても一応プログラミングができることによって、かなり仕事が効率化できるし、問題も解決できるし、いろんなことができるようになる。みんな覚えるといいよねと思います。
自分で使う分には処理が重かろうが最新のブラウザでしか動かなかろうがコードが汚かろうが関係ないし。
プログラミング教育の必修化は賛否両論あるけど、自分はわりといいと思う。本日のところは以上です。

【PR】
このような苦労のもとに運営しております、
f:id:slideglide:20171206234431g:plain
デイリーポータルZをよろしくお願いいたします。記事投稿コーナーもあるのでブログ書いてる人は送ってね。

買物コーナー

寒くなったので部屋用ソックス買いましょう。

*1:AIとかではなくて、Rubyで簡単な文字列処理をしているだけです

*2:Arduinoの開発環境を使っています

*3:マイクロソフト製のエディタ

*4:Webサーバです。Webページをインターネットに公開するためのプログラム。

*5:サーバーサイドJavaScript環境。次のWebpackを動かすためにも必要

*6:自分がバラバラに書いたjsとかcssとかライブラリとかをいい感じにまとめてくれるビルドツールっぽい

*7:ページの見た目とかUIとかを作りやすくするフレームワーク

*8:CSSをもっといい感じの文法で書けるやつ。コンパイルにビルドツールが必要

*9:Single Page Application。ページ遷移しながら使うWebシステムではなく、1ページの中でいろいろ操作できるやつのこと

*10:UIを作るためのJavaScriptフレームワーク。SPA用というわけではないけど簡単なのはこれでできそう。本格的にSPAやるならそれ用のプラグインがあるっぽい

*11:ページの見た目とかUIとかを作りやすくするフレームワーク

*12:非同期通信を制御するやりかた

*13:データベースエンジン。データを保存できる。

*14:ブラウザに情報覚えさせとく方法で、クッキーより大容量