Goalist Developers Blog

モブプログラミングおためし会をやってみた

こんにちは。イイオです。
先日社内でモブプログラミングのおためし会を行いました。

モブプログラミングとは
  • チーム全員が集まって
  • ひとつの開発機を使って
  • ひとつの開発課題に取り組む
  • プログラミング手法!

こちらのスライドも参考に

モブプログラミングという働き方 #DevLOVE // Speaker Deck

社内ではこちらのブログを発端に話題となりました。

技術なきマネジメントの衰退とその対策 - メソッド屋のブログ

発達した上腕を持つCTOの日報でも

6.報連相
自分が知っている技術をチームにまとめて伝授するには、効率的な感じがします。
一度開発部で試してみたいです。

社外に常駐中のエンジニアfromヨルダンの日報でも

5.今日のポジティブ
・モブプログラミングをやって楽しいです!
・やる気で燃えてます!!

なんだか楽しそう〜〜
そんなわけで

試しにやってみた

お題

Kotlinでボタンを押すとHelloWorldするAndroidアプリをつくる

場所

社内のソファスペース(ローテーブル+プロジェクター)

時間

2時間

参加者たち

ドライバー

f:id:y-iio:20170713204916p:plain
イイオ
備考: 本来はドライバーは交代制だがワッタワッタしていてそれどころではなかった

ナビゲーター

f:id:y-iio:20170713205920p:plain
プロ
備考: 最近個人事業主になった

f:id:y-iio:20170713210013p:plain
新卒
備考: チャームポイントはメガネ

f:id:y-iio:20170713210040p:plain
新卒
備考: チャームポイントはメガネ

f:id:y-iio:20170714202546p:plain
開発部リーダー(今月から)
備考: 大阪事業所からのリモート参加

f:id:y-iio:20170713210213p:plain
唯一のモバイルエンジニア
備考: だが他の仕事が押していたので遠まきに声をかけるのみ

f:id:y-iio:20170713211352p:plain
CTO
備考: ねつがでたのでおやすみ

備考: 全員モブプロやったことない

一抹の不安ッ!

楽しげな様子をご覧ください

f:id:y-iio:20170713210942j:plain
こんな感じの場所でやりました。

f:id:y-iio:20170713211137j:plain
やる気を見せつける新卒

f:id:y-iio:20170713210755p:plain
はじめてのAndroid Studio

f:id:y-iio:20170713211103p:plain
試行錯誤…

ふりかえり

結果として

がなりグダグダな進め方になってしまいました…が
課題・目標設定とその共有が大事だ!!!という気づきを得ました

よかったこと

  • 他の人の取り組み方が見れて面白い
  • 会話が多くなりコミュニケーションコスト下がる

反省点

  • プロジェクターに映すと文字見辛い
  • リモートで画面共有しても見辛い
  • とにかく見辛い
  • 明確なゴールを開始時に設定できていなかった
  • ドライバーの入れ替わり制がすっぽ抜けた
  • 全員電池が切れる

次はこうしよう

  • 会議室の大きい解像度高いディスプレイ使って文字見やすくする
  • 知識共有が単直に利になるような、実務に即したお題を設定する
  • ファシリテーターを立てる
    • コーディング始める前に作業の流れを相談&書き出す
    • 15分ごととかでタイマー鳴らしてドライバー入れ替える
  • 電源持参する

はい

何でもできることからひとつづつすね…
次回は来月にでもやってみたいと思います。開発部リーダーが東京にやってくる日を狙います。

もうひとりの新卒二期、自己紹介

こんにちは、開発部の小野です。今年の四月から働き始めました。今回は自己紹介をさせて頂こうと思います。どうぞよろしくお願い致します。

先日一生懸命通勤していた時の話なんですが、一生懸命なあまり、そのときカバンが開けっ放しなのに気付かなかったみたいです。おかげで走っている途中にサイフを落としてしまいました。。。あああ。。そのときどこを見渡してもサイフは見つかりませんでした。

サイフが無くなってとても悲しかったので、「すみません、サイフが消えました。」と連絡し、その日は遅刻しました。怒られました。下の写真、真ん中が僕になります。

上司の発達した上腕から繰り出される平手を受けました。(嘘)

ゴーリストは根性論を重視した体育会系の会社です。(多分嘘)

僕のサイフはどこですか?(激涙)

f:id:f-ono:20170712171314j:plain

入社まで

都内の四年制の大学(教育学部)を卒業しました。プログラミングはほぼ未経験です。一度自分で触れてみたりしたんですが、「、、、無理じゃね?」とか思ってました。

人の紹介でゴーリストに来てみたところ、入社させていただくことができました。

特にかっこいいことは言いませんでしたが、入社できたので、きっと人物本位の採用をしていただけたんだと思います。

大学では演劇で四年間程役者をやったり、一年間引きこもってカラオケで歌を練習する生活をおくったりしていました。

兵庫県出身で関西弁が喋れますが、普段は標準語を話します。社長と地元が一緒でした。

入社からこれまで

四月からいきなりプログラミング研修でした。課題の量が多かったので大変でしたが、結構楽しい日々を送れました。新卒はみんな二か月プログラミング研修を受けるみたいです。

「、、、無理じゃね?」と思っていたプログラミングでしたが、素晴らしい研修のおかげで、無理なく身につけることができました。

おかげで、どんなことも学習すれば、身につけることができるんじゃないかという自信がつきました。とても感謝しています。

入社してみると同期が六人いました。来年は十人入るそうです。圧倒的成長中です。

愛する同期たち

新卒二期、ブログを書く(デザインチーム編) - ゴーリストデザインブログ

新卒二期、ブログを書く(セールス編) - ゴーリスト セールスチームのブログ

新卒二期、ブログを書く - Goalist Developers Blog

(coming soon…)

これから

開発部同期の自己紹介にもありましたが、

・開発部エンジニアとして独り立ちする。

・HRogチャートをより魅力的なサービスにカイゼンする。(HRogチャートというのはゴーリストの提供する主要サービスの一つです。)

のがこれからの目標です。HRogチャートという主要サービスに関わる中で、エンジニアとして独り立ちできるだけの、知識と経験が身につけばいいなと思います。

その過程で分かったことや、大変だったことなどもブログで発信していけたらと思います。

ゴーリストについて

ゴーリストは『自然体』をモットーにする会社です。『自然体』で働くことに共感する人には魅力的な会社なのではないかなと思います。

『自然体』でいられるために大事にされていることがあります。それが八つのバリュー(https://recruit.goalist.co.jp/culture.html)の中にもある「当たり前の徹底」です。

「当たり前の徹底」の中には、「時間や納期を守る、約束を果たす、クライアントの要望通りに応える。 そしてもし不満やクレームが起きたとしても、どこよりも速く対応し、リカバリーする。」と書かれています。

入社四か月目の僕から見て分かる「当たり前の徹底」は、遅刻しない、五分前に集合するということです。ゴーリストで遅刻は厳禁です。上の方にはスクロールしないでください。

それさえ守れば、きっと『自然体』でいられる会社が待っているんじゃないかなと思います。

どしどし募集中

新卒、中途の方々全方位で絶賛募集中です。

「自然体」で働くことに興味がわいた方、なんか面白そうって思った方是非社内の見学や、話を聞きに来てくださればと思います。

新卒の方は採用イベントなども打ち出していくので、お会いすることもあるかもしれませんね。

参考URL

【HRogチャート】

https://chart.hrog.net/

【採用ページ】

recruit.goalist.co.jp

新卒二期、ブログを書く

こんにちは開発部のバンナイです。 今年の4月から新卒で働き始めました。新卒二期です。 先輩に倣ったブレ芸です。先輩ほどキレがよくない。

ブログを書くと言っても今回はただの自己紹介です。

f:id:bbbbbbbbb9:20170706131311j:plain

ちなみにこちらは去年の新卒の自己紹介です。必見のブレ
新卒エンジニアブログを書く - Goalist Developers Blog

入社まで

都内の四年生大学(工学部)を退学しました。プログラミングは未経験です。 パソコン自体Wordで適当なレポートを書いたりAmazonでお買いものするぐらいしか使ったことなかったです。

ちなみにインドア派でもアウトドア派でもありません。

自分でこれがウリですと言えるようなことは特にありませんでしたが、雑談(いや、面接です)を重ねる中で会社の掲げるバリューに対して適合度が高いとのことで入社させていただくことになりました。

ゴーリストはバリュー(価値観)を重んじる会社なのです。

これまで

4月から7月まで三か月間は開発研修を受けていました。 Java、AWS、MySQL、Play framework、Angular等を駆使し、最終的には自分一人でWEBサービスを作り上げることができるようになる、ということを目標に据えての研修でした。

課題では一つ一つやることが明確で切り離されていること、次の課題をこなすには以前の課題の内容をうまくコラボレーションさせていくことが必要だったという二つの理由で以前よりプログラマっぽい考え方ができるようになったのかなと振り返っています。

最終的に「ツリー構造でToDoを管理するアプリ」や「ゴーリストが蓄えた過去求人情報を利用し会社を検索するアプリ」(東京都で年俸が600万以上のITエンジニアの求人を一年前までは出していたが、それ以降は出していない会社。みたいな条件を設定して該当する会社を検索できるアプリケーションです。)等を作りました。

結論、自分一人でWEBサービスを作り上げることができるようになるという目標に関しては人に教えを乞う力を行使することを自分一人の力とすれば目標達成したと言えるのではないかと思います。

というのは冗談ですが人に教えを乞う力の重要さを痛感した三か月でありました。

これから

7月から9月の三か月間での達成すべき抽象的な目標は

  • HRogチャートをより魅力的なサービスにカイゼンする。(HRogチャートというのはゴーリストの提供する主要サービスの一つです。)

  • 開発部エンジニアとして独り立ちする。

そのためにこの三か月間でこなすべき具体的な目標は

  • 顧客訪問同行10社。

  • HRogチャート関連のカイゼンを10個行う。

  • HRogチャートの新機能、運用面での新規課題を10個発見する。

です。これだけやったら開発部エンジニアとして独り立ちできそうですね、、、

達成していきたいです。

ゴ-リストについて

社会人経験が三か月程しかないのでよくわかりませんが世間一般的には緩いと言われる社風なのではないでしょか。

別の言い方をすれば自然体で働ける会社ということです。

ゴーリストの価値観(バリュー)に共感できる人にとっては自然体で働ける良い環境だと思います。

またこのブログの中で目標という言葉が頻出していますね。これは社名の由来にもなったゴールを大事にする社風が反映された結果です。

新卒募集!

最近、社内では次期新卒の採用に向けての動きが活発化しております。 もしブログを読まれてゴーリストで働くことに興味を持たれた方がおられましたら是非一度社内の見学や、話を聞きに来てくださればと思います。

ホームページ等を見て、興味がそそられたのでしたら、実際来てみると楽しい思いができると思いますよ。

ちなみに募集しているのは新卒だけではないです。

参考URL

【HRogチャート】 https://chart.hrog.net/

【採用ページ】

recruit.goalist.co.jp

はじめてのAngular TODOアプリをつくる④ HTTP編

どうも、イイオです。
AngularでTODOアプリ的なものを作ってみようシリーズ、
チュートリアルでいうとこの辺りを見つつ、通信の部分やってきます。

https://angular.io/tutorial/toh-pt6

前回まで一体何をやっていたんだ?漢は過去に拘泥しない。

目標

今回のゴールは「HTTP通信してWebAPIを呼び出し、データのやり取りを行う」ことです。
でその際に
チュートリアルではObservableに包まれて来るレスポンスを.toPromise()でPromiseに変換してるけど
Observableをそのまま使うのがゴーリストではスタンダードっぽいのでそれに準じてます。

やること

  1. InMemoryWebApiModuleを使ってAPIサーバ風にふるまってもらう準備
  2. Observableを使ってHTTP通信する

1. InMemoryWebApiModuleを使ってAPIサーバ風にふるまってもらう準備

Webサーバのシミュレーションしてくれる機構が用意されています。

なぜか入ってなかったのでnpmで取ってきた

npm install angular-in-memory-web-api@latest

angular2の場合はangular2-in-memory-web-apiかもしれない

DBのふりするサービスを作成

ng g service in-memory-data

mock-tasks.tsからモックデータをコピってきて中身はこんなかんじに

in-memory-data.service.ts

import { Injectable } from '@angular/core';
import { InMemoryDbService } from 'angular-in-memory-web-api';

@Injectable()
export class InMemoryDataService implements InMemoryDbService {

  constructor() { }

  public createDb() {
    const tasks = [
      { id: 0, name: '', importance: 'high', isDone: false },
      { id: 11, name: '企画ロードマップ作成', importance: 'high', isDone: false },
      { id: 12, name: '山田さんにメール返信', importance: 'high', isDone: false },
      { id: 13, name: 'Angular2キャッチアップ', importance: 'mid', isDone: false },
      { id: 14, name: 'ブログ更新', importance: 'low', isDone: false },
      { id: 15, name: '新卒技術研修', importance: 'low', isDone: false }
    ];
    return tasks;
  }

}

http://localhost:4200/api/tasksをエンドポイントにGETすると
Response.json().dataでこの配列が返って来る。なんでか知らないけど返って来る。
わからなくても使えればいいんだなあ いいを

このサービスをapp.module.tsに登録して使えるようにする

import { InMemoryWebApiModule } from 'angular-in-memory-web-api';
import { InMemoryDataService }  from './in-memory-data.service';
・・・
@NgModule({
  imports: [
    ・・・
    InMemoryWebApiModule.forRoot(InMemoryDataService),
  ],
  ・・・
})

2. Observableを使ってhttp通信する

とりあえず全データ取得するやつをちゃんと動くようにしてみようかと。
前々回くらいに作ったTaskサービスを書き換えます。

task.service.ts

import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/switchMap';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/of';

@Injectable()
export class TaskService {
  private headers: Headers = new Headers({'Content-Type': 'application/json'});

  constructor(private http: Http) { }

  public getTasks(): Observable<Task[]> {
    const url = 'api/tasks';
    return this.http.get(url, {headers: this.headers})
      .switchMap((response: Response) => {
        return Task.toTasks(response.json().data); // チュートリアルみたいに as Task[] ではキャストできなかった
      })
      .catch((error) => {
        throw new Error(error); // なんかエラー出たら呼び出し元の方でで受け取ってもらう
      });
  }
  
}

そうしてObservableにくるんだオブジェクトを呼び出し元に返してあげる。
呼び出し元ではObservableで返ってきたオブジェクトをsubscribeしたら使える状態になります。

export class TasksComponent implements OnInit {
  private tasks: Task[];

  constructor(private taskService: TaskService) { }

  ngOnInit() {
    this.getTasks();
  }

  private getTasks(): void {
    this.taskService.getTasks()
      .subscribe(
        (retTasks: Task[]) => {
          console.log(retTasks);
          this.tasks = retTasks;
        },
        (error: any) => {
          console.log(error);
        }
      );
  }

}

よし!!!!目標達成!!!!!
同様にしてデータ作成・更新・削除のメソッドを作れば完成!!!
大胆にも割愛する勇気ッ!!!ソイヤッソイヤッ

はい

というわけで、Observableからのsubscribeする流れの一例として見ていただければと思います。

Q. TODOアプリ完成させないんですか?
A. 完全性は地獄に置いて来た

誰の役にも立たないものを作るのはつらい。自分のためか。
とはいえ新卒も加入してどんどこ更新してくれるらしいのでエンジニアブログの未来は明るい。
明るい!

はい

最近業務でWebアプリをリリースしました。
チュートリアルを完走する前に本番の締切が来た。
フロントはAngularによって書かれています。できたてホカホカです。

map.hrog.net

企画とかからやらしてもらってます。

イベント告知

2017年7月21日(金) 19:30〜21:30、ゴーリスト東京本社にて
AWS Lambdaを中心に、サーバレスアーキテクチャを勉強する会
が開催されます!

connpass.com

このブログでもシチメンロッピの活躍中の盛次さんが登壇します。
すでに席はかなり埋まってしまっていますが、ご興味あればぜひ٩( ‘ω’ )و

はい

そんなかんじです

StoryboardのPreview機能の使い方

こんちは。渡部です。
初めて健康診断でバリウム飲みました。
お腹が痛いなうです。

f:id:watabe1028:20170629112824p:plain

今回はXcodeのPreview機能について紹介します。

なぜこの機能かというと
恥ずかしながら未だにAutoLayoutが苦手です。
きっとAutoLayoutが苦手な人はたくさんいるはず。。。

そんな人のための機能?とも言えるPreview機能、
知らない人もたくさんいるのでは?と思い書こうと思いました。

Preview機能とは

簡単に言うと
「複数端末のレイアウトをリアルタイムで一度に確認できる」
機能です。
ビルドの必要なし。
すぐに反映されます。

起動手順

1.XcodeでStoryboardを起動します。

f:id:watabe1028:20170629113250p:plain

2.右上のボタン押して二画面表示にします。

f:id:watabe1028:20170629113436p:plain f:id:watabe1028:20170629113523p:plain

3.Previewを選択します。

f:id:watabe1028:20170629113641p:plain

左画面がStoryboard、右画面がPreview画面です。 f:id:watabe1028:20170629113710p:plain

使用方法

とりあえずStoryboardに以下のUIKitを配置します。

UILabel、UIImageView、UIButtonを配置。

f:id:watabe1028:20170629113910p:plain

表示したい端末を複数選択します。

Preview画面左下の「+」ボタンから端末を選択します。

f:id:watabe1028:20170629114139p:plain

選択順に並びます。

f:id:watabe1028:20170629114207p:plain

すでに画面が崩れてますね。。。

あとはStoryboardをいじいじするだけです。
いじいじするとリアルタイムで各端末毎に反映されます。

では軽くAutoLayoutを設定してみます。

中央揃えしてみて、、、

f:id:watabe1028:20170629114256p:plain f:id:watabe1028:20170629114313p:plain

こう!

f:id:watabe1028:20170629115638p:plain

全端末がいい感じになりました。

まとめ

もっと早くこの機能を知っていれば。。。
この機能知らないと、シュミレータで毎回ビルドしていた人もいると思います。
Storyboardによってフロントの開発効率は上がりましたが
複数端末対応にかなり手間取っていました。 このPreview機能を使ってより効率的に開発できるようになります。

Xcodeの隠された便利機能、引き続き紹介していけたらと思います。
ちなみに使用している画像は弊社新サービスの「HRogマップ」です。

map.hrog.net

Lambda & PhantomJS & Selenium WebDriver for Java

f:id:t-moritsugu:20170623103856p:plain
こんにちわ、 ゴーリスト開発のモリツグです。
EC2インスタンス100台で毎日クローリングしてたら請求額が洒落にならなくなったので必要にせまられてLambdaでクローラを作ることにしました。
あっさりできるかと思ったのですが、思いのほか手こずったので同じ経験をする人が居なくなることを願ってブログに残しておこうと思います。

今回の課題を列挙してみます
1.Lambda & PhantomJSで複数のフォントを見れるようにする(日本、中国、韓国、タイ、アラビア、ヘブライ)
2.PhantomJSはSelenium WebDriverを使ってJavaから操作する
3.クローリング結果の一時保存以外では/tmp領域は使わない

Lambda & PhantomJSで複数のフォントを見れるようにする 前半

とりあえずリクルートさんのブログが参考になります。
LinuxのPhantomJSはfontconfigに依存しています。
Lambdaにはデフォルトでfontconfigは入ってないので日本語などは文字化けします。
Lambdaでユーザが一時的に自由に扱える領域は/tmpだけです。とりあえず/tmp以下にfontconfigをぶち込めば動くのですが、/tmp以下に同じ名前のディレクトリを作ると衝突することがあるので乱数をつけたり衝突を回避する手段が必要です。
ここで制限つきですが、もう1ヶ所それなりに好き放題できる場所があります。
それが/var/task以下です。Lambdaでとりあえずpwdすると/var/taskが返ってきます。
jarやzipが展開されるディレクトリもここになります。書き込みはできません。(これが制限になります)
したがってここにfontconfigをつっこみます。 私の環境はWindows7だったので、とりあえずVagrantでVirtualBoxにCentOSをインストールしました。
https://github.com/2creatives/vagrant-centos/releases/tag/v6.4.2

せっかくminimalなのに無理やりGUIを入れたせいでちょっと大変でしたが、みなさんはminimalのままで良いと思います。
では先ほどのブログを丸ぱくり参考にして設定をしていきます。

#無心で以下のコマンドを打ちます。  
yum install epel-release  
  
#PhantomJSをインストール
rpm -ivh http://repo.okay.com.mx/centos/6/x86_64/release/okay-release-1-1.noarch.rpm  
yum search all phantomjs  
yum install phantomjs.x86_64  

# 一旦アップデート
yum update

# GUIとかいれてるせいで怒られる
yum update --skip-broken

# 依存ライブラリをインストール
yum install gperf freetype-devel libxml2-devel python-lxml

# ソースを落としてディレクトリ移動
git clone http://anongit.freedesktop.org/git/fontconfig
cd fontconfig

# configure
./autogen.sh --sysconfdir=/var/task/fontconfig/etc --prefix=/var/task/fontconfig/usr --mandir=/var/task/fontconfig/usr/share/man --enable-libxml2

# make & install
make
make install

# 上手くいけばいいが、以下のエラーで怒られた
# ImportError: No module named six.moves
# とりあえずpipを落としてきてインストール
cd ..
curl -kL -O https://bootstrap.pypa.io/get-pip.py
python get-pip.py

# pipをアップデート python2.6早くアップデートしろ!と出てるが一旦無視
# pip install -U pip

# なんかエラーでるけどとりあえず入る
pip install six

# とりあえずmakeしてみたら通った
cd fontconfig
make
make install

Lambda & PhantomJSで複数のフォントを見れるようにする 後半

引き続き、最初に紹介したブログを丸パクリ参考に設定を進めていきます。
/var/task/fontconfig/etc/fonts/local.confというファイルを以下の内容で作成します。

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
  <dir>/var/task/fontconfig/usr/share/fonts</dir>
</fontconfig>

続いて、/var/task/fontconfig/usr/share/fontsというディレクトリを作成し、 IPAフォントとかを突っ込んでおきます。

mkdir /var/task/fontconfig/usr/share/fonts/
curl http://dl.ipafont.ipa.go.jp/IPAexfont/ipaexg00301.zip > ipaexg00301.zip
unzip ipaexg00301.zip
cp ipaexg00301/ipaexg.ttf /var/task/fontconfig/usr/share/fonts/

ここまででPhantomJSで無事に日本語が表示できるかを確認します。
以下のようなファイルを作成しcap.jsという名前で保存してください。

var page = require('webpage').create();
page.open('http://developers.goalist.co.jp/entry/2017/06/23/120000', function () {
    window.setTimeout(function () {
        page.render('debug.png');
        phantom.exit();
    }, 5000);
});

フォントキャッシュを再構築して実行

/var/task/fontconfig/usr/bin/fc-cache -fs
LD_LIBRARY_PATH=/var/task/fontconfig/usr/lib/ phantomjs cap.js

日本語以外のフォントも見れるようにする

基本は yum search thai font とかして出てきたなかで一番それっぽいフォントを入れます。 あんまり色々なフォントを入れるとLambdaのデプロイ上限の250Mを超えます。
yum installすると/usr/share/fonts/にインストールされるので/var/task/fontconfig/usr/share/fontsにコピーしましょう。
私は本当に大丈夫か確認するためにコピー後にyum removeし、消えないことがあるので/usr/share/fonts/以下の該当フォントをrmで削除しました。
以下は今回入れたフォント一覧です。

韓国 baekmuk-ttf-gulim-fonts.noarch
タイ thai-scalable-kinnari-fonts.noarch
中国(繁体) cjkuni-ukai-fonts.noarch
中国(簡体) wqy-microhei-fonts.noarch
アラビア amiri-fonts.noarch
ヘブライ culmus-aharoni-clm-fonts.noarch

LambdaでPhantomJSをSelenium WebDriverを使ってJavaから操作する

以下は主にJava向けの内容になります。
どの言語にも共通する重要なポイントは「/var/task/libはデフォルトでLD_LIBRARY_PATHに含まれる」という所だと思います。AWSの中のイケメンがやってくれたようです。

今回はeclipseにawsのプラグインを入れてLambdaプロジェクトを作りました。
このあたりは詳しくは説明しませんが、S3とかを扱う目的でaws-java-sdkを入れるとそれだけでLambdaに乗らなくなる可能性があるので、aws-java-sdk-coreとaws-java-sdk-s3だけ入れるみたいな努力が必要です。
Seleniumライブラリ、fontconfigと各言語のフォント、PhantomJSのバイナリを入れるので結構カツカツになります。
適当なフォルダ(今回はdriverという名前)を作ってビルドパスのソースに含めます。

f:id:t-moritsugu:20170623022716p:plain

画像のようにdriverには以下の3つを配置します。
・/var/taskにあるfontconfigディレクトリ
・PhantomJSバイナリ
・LD_LIBRARY_PATHで指定していた/var/task/fontconfig/usr/lib/をlibとして配置

/var/task/libがLD_LIBRARY_PATHにデフォルトで含まれることを利用して/var/task/fontconfig/usr/lib/以下のファイルをそこに配置する目的で置いています。
/var/task/fontconfig/usr/lib/pkgconfig/fontconfig.pcの中とかを見ると絶対パスで色々書かれてるので大丈夫ぽいです。
あとはeclipseの機能でエクスポートから実行可能JARファイルを作成すればいいのですが、ライブラリ形式は一番上の「生成されるJARに必須ライブラリーを抽出」を選んでください。

あとはこれをLambdaにデプロイすればすべて上手く。。。行きません。

以下の2つの問題をクリアしないといけません。
1.PhantomJSや/var/task/fontconfig/usr/bin/fc-cacheに実行権限が無いため怒られる、さらにJARにした段階(antによるjar作成)でパーミッションが引き継がれず事前に実行権限を付与していても実行権限が無くなってしまう。
2.デフォルトでphantomjsdriver.logがカレントディレクトリに作成されるが/var/taskには書き込めないので怒られる。

1については私の環境がWindowsでそもそも実行権限を付与できなかったため、VirtualBoxにCentOSとeclipseをいれました。しかし何故かKDEデスクトップとの相性が悪いせいかJAR作成画面が固まって作れなかったため、Windowsで実行可能JARをつくるときにantファイルを保存してそれを利用するというちょっと特殊なことを行ったので、もしかしたら不正確かもしれません。 ただ、Windowsユーザは事前に実行権限を付与する術がないためLinux環境は必須です。
以下のようなスクリプトを作成し、antファイルを一部書き換えることで無理やり実行権限を引継げるようにしました。肝はfilesetは実行権限を設定できないけれど、zipfilesetはfilemodeで設定できる所だとおもいます。期待通りに固められているかは拡張子をzipとかにして中身を見れば良いと思います。

antの前にゴニョゴニョするスクリプト

#!/usr/bin/bash
cd /work/workspace/Hoge/bin
zip -r bin.zip *
cd /work
ant -buildfile hoge.xml

antファイル hoge.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="create_run_jar" name="Create Runnable Jar for Project Hoge">
    <!--this file was created by Eclipse Runnable JAR Export Wizard-->
    <!--ANT 1.7 is required                                        -->
    <target name="create_run_jar">
        <jar destfile="/work/dest/Hoge.jar" filesetmanifest="mergewithoutmain">
            <manifest>
                <attribute name="Main-Class" value="com.goalist.hoge.LambdaFunctionHandler"/>
                <attribute name="Class-Path" value="."/>
            </manifest>
        <!-- 権限を引き継ぐために一旦事前のスクリプトでzipにしてそっちを使う
            <fileset dir="/work/workspace/Hoge/bin"/>
        -->
        <zipfileset filemode="755" src="/work/workspace/Hoge/bin/bin.zip"/>
            (.....libraryのjar系の記述なので省略.....)
        </jar>
    </target>
</project>

2については–webdriver-logfileパラメータがどうやってもPhantomJSに渡らない(実行時にコンソールでパラメータを確認できる)ので以下のような方法しかなさそうです。

Runtime.getRuntime().exec(new String[]{"/var/task/fontconfig/usr/bin/fc-cache", "-fs"})

String phantomJsBinaryPath = "/var/task/phantomjs"; 
String userAgent = "Mozilla/5.0 (Windows NT 6.0) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1";

DesiredCapabilities capabilities = DesiredCapabilities.phantomjs();  
capabilities.setJavascriptEnabled(true);  
capabilities.setCapability(  
  PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY,
  phantomJsBinaryPath
);

capabilities.setCapability(
  PhantomJSDriverService.PHANTOMJS_PAGE_SETTINGS_PREFIX + "userAgent", userAgent);

File logfile = new File("/dev/null");
PhantomJSDriverService pjsds = new PhantomJSDriverService.Builder()
  .usingPhantomJSExecutable(new File(phantomJsBinaryPath))
  .usingAnyFreePort()
  //.withProxy(proxy)                       
  //.usingCommandLineArguments(commandLineArguments)
  .withLogFile(logfile)
  .build();

return new PhantomJSDriver(pjsds, capabilities);

やっとLambda上で快適にクローリングできます!

まとめ

Javaじゃなかったら最後の方の問題は関係ないと思います。
この作業中に仮想環境が2回ぐらい壊れて再インストールしたので物凄く疲れました。
Lambdaは夢が広がるので面白いなぁと思います。

バックエンドエンジニアがフロントエンドを書く① 〜React、storybookのセットアップ〜

現プロジェクトでバックエンドを実装しているJPです。 ですが、フロントエンドのReactとstorybookを使った開発に興味を惹かれたため、自分でReactプロジェクトを作成してみたいと思います。

筆者の経験:CLIツールなどもあまり触ったことがない、フロントエンドの初心者
環境   :macOS Sierra

目次

Reactとは

facebook が開発した素晴らしい描画ライブラリだということしか知りません。
申し訳ありませんが、説明は端折らせていただきます。

storybookとは

簡単に言うと、React で作成したコンポーネントを1つづつ見ることができるカタログのようなもののようです。
github.com

各種ツールをインストールする

homebrew

インストール手順:Homebrew — macOS 用パッケージマネージャー

npm

ホームディレクトリで以下のコマンドを実行

brew install node
node -v
npm -v

yarn

特に理由はありませんが、フロントチームが使っていたので、yarnを使ってみます。
npmみたいなツールのようです。
GitHub - yarnpkg/yarn: 📦🐈 Fast, reliable, and secure dependency management.

npm i -g yarn@0.19.1

storybook

npm i -g @storybook/cli

create-react-app

Reactプロジェクトを自動で作成してくれるCLIツールです。
eslintやbabelなどの推奨されるライブラリも自動で落としてくれるようです。

npm install -g create-react-app 

これで準備は完了です。

React プロジェクトの作成

作業ディレクトリへ移動

cd プロジェクトを作成するディレクトリ

新規プロジェクトの作成

create-react-app my-app

こんな感じのフォルダができました。
依存ライブラリは my-app/node_modules 以下にあります。
f:id:j-itoh:20170615192836p:plain

プロジェクトの起動

cd my-app
yarn start

こんな画面が表示されます。これだけでアプリケーションとして動くようです。 f:id:j-itoh:20170615193839p:plain

storybookのセットアップ・起動

my-app直下で以下のコマンドを実行

getstorybook
yarn run storybook

http://localhost:9009/にアクセスすると、以下のページが表示されます。 f:id:j-itoh:20170615200240p:plain

以上で storybook が起動するところまで完了です。
最初に React プロジェクトを作成しなければならないこと以外は割りとスムーズにできました。
ここまで自動化されているとありがたいです。

次回

次回は以下の内容について書きたいと思います。

  • KNOBSアドオンを追加する
  • Material-Uiのコンポーネントを追加する
  • コンポーネントを中央に配置する