生半可な気持ちでプログラマになった男日記

日々地獄の中をさまよっている糞雑魚プログラマの技術ブログ。テニスが好きです。

Osaka Mix Leap Study #23 - React Native 勉強会に参加してきました

9月19日に Yahoo! JAPAN の大阪オフィスで開催された Osaka Mix Leap Study #23 - React Native 勉強会に参加しました。

yahoo-osaka.connpass.com

確か台風の影響かなんかで振替開催された勉強会です。

参加してみて

正直今の段階で React Native を使うのはちょっとこわいなーって感じがしました。

主にそう感じた部分は以下の点。

  • ネイティブ側のビルドでこけたらデバッグがめちゃめちゃつらい
  • ネイティブ側の実装を触りたい場合はブリッジという機能を使うらしいが、 ネイティブ側のプログラミングができる人じゃないときつい
  • React Native はネイティブ実装と同等のことを実現するのが難しい場合がある(React Native パッケージの API の都合)
    • ある程度仕様をコントロールできる案件でないときつい

自分はネイティブのプログラムはあまりやったこと無いので、ネイティブ側でコケた場合は確実にハマる自信がある。

社内でネイティブエンジニアがいる場合は相談とかできるしいいかもしれないですね。

あと一番重要だと思ったのは、仕様をコントロールできる案件でないときついというところ。

今自分が働いてる職場でも React Native で制作しているアプリ案件があるのですが、仕様のコントロールが完全に先方なのでかなり苦労してました。

先方)ここの機能追加してくれー → 弊社)React Native で実装するのきついなぁ → 先方)知らんやん、やれ → 絶望

上記みたいなパターンのやりとりが弊社でも発生しててほんとしんどそうでした。

実際、ネイティブエンジニア総出でやってたりしてたのできつそうなイメージしかなかったです。

結果

Web サービスの体験を良くするためにアプリとして作りたいというなら採用してもいいかもと思いました。

たとえばシンプルなアプリ(ニュースアプリや掲示板アプリ)とか。反面、ネイティブの機能をよく使うアプリはどうかなと思います。カメラアプリとか。

WEBエンジニアの知識で iOS/Android の開発ができるところはとても魅力的ですが、 React Native の頻度の高いバージョンアップへの対応と、採用しているプラグインのバージョンアップ対応が追いつかなかったりするところが採用にブレーキをかけてしまう原因となってます。

ネイティブ周りの人材が豊富な企業などはネイティブでアプリ制作するのが無難かなーと思いました。

議事録

19:05-19:25 「React Nativeでモバイルアプリ開発をはじめよう!」 藤本 卓哉(株式会社Gemcook)

  • 代表兼エンジニア
  • AWS大好き

  • 対象の人

    • Reactわからん
    • ReactNativeが難しそうで取っ付けない人
    • 最近入門した人
  • ゴール

    • ReactNative でアプリ作りたいって思わせる
  • React復習

    • React ってなに? - UI構築のJSライブラリ(Angular/vueと同じ土俵)
    • 設計思想
      • 宣言的
        • jqueryは命令的、状態が合ってそれをどうするかっていうのがReact
      • コンポーネントベース
        • DOM + 処理で部品と考える
        • 状態管理が便利
      • 一度学べばどこでもかける
        • WEB/VR/アプリ 何でもかけるよ、これが一押しなんやで
      • 使う理由
        • 状態持った部品として使える
        • 仮想DOM の高速レンダリング
        • ライブラリの充実
        • ReactNative の存在、これがあるから Gemcook が使ってる理由
          • 好きな会社が使っている
          • Facebook製だから
  • ReactNativeとは
    • RN = ReactNativeのことだよ
    • ネイティブモバイルを構築するためのJSライブラリ
    • インスタ/スカイプ/ピンタレスト/ウーバーが使ってるよ
    • iOS/Android 一度にかけることが激アツ
    • ReactNative 使えばエンジニアの人材不足を回避できるよ〜
    • フロントエンド無双できるよ〜フルスタックなれるよ〜
    • ライバル
      • angular + native script
      • vue + weax
      • なんで ReactNative 選んだか
        • Facebook の歴史にあり
          • ハイブリットアプリの時代があった
          • 重すぎて株価暴落、でもHTML5 は悪くないよーてCEOがいってた
          • ReactNativeの開発スピードはすごい早いよ
          • ReactNativeのバージョンあがるとめちゃめちゃビルドこけるよ
            • 俺もつらかったからみんな記事あげてな
        • ビルドスピード早いからサクサク開発できる
        • 全体の学習コストを低下できる(各言語)
        • iOS/Android 両方ビルドされるからリリースまでの時間短縮できる
        • UI/UXの開発に時間さける
        • 有名企業が扱ってる安心感
        • デメリット
          • Native側のビルドでこけたらデバッグがめちゃめちゃつらい
          • 検索してもでてこないとかあったで
          • つまずくとしたらこのポイント
          • iOS/Android に新機能追加したらReactNativeの開発まちになる
          • bridge?という昨日を使えば回避できるらしいがしんどい
    • airbnb のソース見るとかなり勉強になるしわかりやすいよ〜
    • airbnb の撤退はマイナス的な撤退じゃないよ
      • RNの選択肢は最高だった
      • airbnbの成長がReactNativeの成長を上回っただけ
      • 人材確保の面などをふくめて

19:25-19:45 「WebエンジニアがReact Nativeで開発した気づき」 言上 和也(ヤフー株式会社)

  • アジェンダ
    • 導入の経緯
      • 開発案件
        • 訪日外国人向けのアプリ作りたい
        • 構造はシンプル・ニュースサイトだった
        • 4ヶ月ほどの開発期間
        • iOS/Android 両方ほしい
      • 俺Webしかやったことない・・社内にアプリ開発の知見もない・・・悲しい
      • 上司が ReactNative を提案
      • バージョン0.Xだったから導入にすごく不安だったけど学習コストの面考えて採用した
      • learn once,write anywhere の体現がよかった
      • 短期間でのJava/Swiftをやること考えるとまだましだった
      • 1ヶ月で企画・学習
      • 1ヶ月半でiOSリリース
      • 1ヶ月でAndroidリリース
    • 実装できた理由・辛かったとこ

      • 自分が優秀だったから実装できたわけではない
      • ポイント
        • learn once,write anywhere の体現
          • ReactとReactNativeのライフサイクルが同じ
          • iOS/Androidの違いなし
          • OSSが使用できる
            • 特にデータフロー周りが充実してた
              • redux,redux-saga,redux-loggerなど
        • WEBの知見がいかせる

          • npm 使えることの楽さ
          • DOM操作以外のOSSは基本使える
            • fetch,date-util,dotenv,loadash
          • レイアウトがCSSで調整できる、flexboxでレイアウトされてるよ
          • ReactNativeの足りない部分は簡単に使えるように外国人がライブラリ作ってくれてる
        • OSSを使った効率向上

          • 体感的に7~8割共通化出来た
          • 画面周り以外は共通化できる
    • WEBエンジニアから見たReactnative

      • 想像以上にコードの共通化できる
      • ホットリロードが便利
      • web知見活かせる
      • react知ってるとだいたいできる
    • 手放しにおすすめはできません
      • はまるとやばい、抜け出せない
      • モバイルの知見は必須(ネイティブ皮がもってる昨日など)
      • 各モバイルの開発環境は必要
      • deploy周り(React の知識では補えない)
      • UXの違い
      • 凝った開発するとネイティブすぐさわらなあかん
      • バージョンアップがすごいはやい間隔でされる
      • 公式のバージョンアップでライブラリ開発者がおいつけずOSSの更新とまっちゃう
      • OSSライブラリでiOSちゃんと動いてるけどAndroidが弱かったり、その逆もしかり。。。ということがようある
      • とにかく deploy まわりがつらすぎた
      • ReactNativeのバージョンアップがつらすぎる
      • ドキュメントが英語
      • エラーログで探しても情報が出てこない
      • ある程度仕様をコントロールできないとつらい、代理店様様ではやばい
    • ReactNativeに合う案件
      • こだわり<スピード
      • 要件シンプル
      • ミニマム機能で早くリリースしたい
      • iOS/Androidの開発が必要

19:45-20:05 「Gemcookで使うReact Nativeで絶対使えるライブラリ」 西野 竣亮(株式会社Gemcook)

  • アジェンダ
    • ライブラリとは・何ができる?どこまでできるの?部分
      • React単体では動かないからCreateReactAppを実行するよ
        • Reactを立ち上げるための準備を一通りしてくれるよ
      • 自分らがつくってるものはライブラリの寄せ集め
    • 使えるライブラリ
      • ReactNativeのライブラリの特徴
        • ルーティング(画面制御系)
          • ReactNavigation
            • 細かいとこまで作り込めるよ
            • StackNavigator
              • 画面の重なりを表現するルーティング、iOSでよくあるやつ
            • TabNavigator
              • よくあるやつ、ただのタブ
            • DrawerNavigator
              • 開発途中で安定してないので今は使わないほうが良いよ
            • Fluid Transitions for React Navigation
              • かっこええ演出つくれそうやで
          • react-native-router-flux
            • めちゃめちゃ簡単やからひとまずルーティングしたいだけならこれも使えるよ(案件ではおすすめできないかも)
        • Native機能系(カメラとか)
          • react-native-splash-screen
            • componentdidmountでスプラッシュスクリーンの制御できる、簡単に使えるよ
          • react native camera
            • カメラ使いたい時はとりあえずこれ
            • 写真・動画・顔認証・バーコードスキャン機能あるよ
          • react-native-maps
            • propsを流し込むだけで、Mapを表示できる
            • 導入部分で挫折する人多いけど、高機能だからとてもおすすめだよ
            • MAP使ったアプリを作る時はおすすめ
            • テーマも選択できるよ(ダークとか)
        • UI系(今回紹介するのは簡単なやつやで)
          • NativeBase
            • ReactNative界のBootstrap
            • Androidはマテリアル
          • react-native-vector-icons
            • とりあえずいれとけ
          • react native blur
            • 画像系?
          • react-native-lightbox
            • ページ遷移なしで画像拡大機能あるよ
          • lottie for react native
          • react-native-app-intro
            • オンボーディングを構築できるライブラリ
            • 鬼簡単に実装できる
            • おすすめやで
    • 自社OSSの紹介(githubでも公開してるよ)
      • ESLint-config-gemcook
      • gemcook/table
      • gemcook/pagination

PHP 公式の Docker イメージを使って PHP + Apache + Xdebug の環境を構築する

案件で Docker を使って開発環境の構築をしたのでメモとして残しておきます。

今回作成したファイルの Github ページはこちらです。

github.com

構築する環境

Docker Compose を使って以下の条件を満たした開発環境の構築を行います。

先輩からの強いおすすめにより、今回は Docker Compose を使って環境を構築したいと思います。

今回は PHP7.1 の Apache サーバーのみで Web サーバーのコンテナしか作成しないので Docker Compose で作成してもあまり意味ないかもしれませんが、 DB サーバーいれて開発環境を整えることの方が多いと思うので、勉強がてら Docker Compose で構築します。

インストール

自分は Mac なので Docker for Mac を以下のページからインストールします。

ちなみに会員登録しないとインストールできないようですね。

Docker Store

f:id:pachory:20180915232327p:plain
Docker Store

インストールしたら docker コマンド使えるようになってますので、バージョン確認とかしてみてちゃんと動いてるか確認しましょう。

docker version

f:id:pachory:20180915232420p:plain
docker version

今回利用するコマンド達

今回 Docker Compose で環境構築する際に使ったコマンド達です。

build

docker-compose.yml ファイルを元にビルドする。

docker-compose build

up

docker-compose.yml ファイルを元にコンテナの作成+起動を行う。

docker-compose up -d

オプションで -d をつけることでバックグラウンドで実行可能。

down

docker-compose.yml ファイルを元にコンテナの停止+コンテナの削除を行う。

docker-compose down

start

コンテナを起動する。

コンテナが存在する場合にのみ実行可能。

docker-compose start

stop

コンテナを停止する。

コンテナは削除しない。

docker-compose stop

ps

現在のコンテナ情報の一覧を表示する。

docker-compose ps

exec

コンテナのプロセスを実行する。

bash オプションを追加することでコンテナ内にアクセスできる。

docker-compose exec サービス名 bash

設定ファイルの作成

yml ファイルの作成

今回作成するサービス情報を docker-compose.yml に定義していきます。

version: "3"

services:
  web:
    container_name: web_container
    build: .
    volumes:
    - マウント元のローカルディレクトリパス:マウント先のディレクトリパス
    ports:
    - 8800:80

build の項目は Dockerfile があるパスを入力します。

今回は web サーバーのみなのでこのファイルは以上です。

Dockerfile ファイルの作成

使用するイメージファイルの指定や、コンテナ起動後のサーバー内で実行するコマンド等を定義していきます。

今回は CakePHPXdebug が動く環境を設定したいのでそのインストールコマンドなどを定義していきます。

# イメージファイルの指定
FROM php:7.1-apache

RUN apt-get update

# vim インストール
RUN apt-get install -y vim

# php 拡張のインストール
RUN apt-get install -y libicu-dev libpq-dev
RUN docker-php-ext-install intl pdo pdo_pgsql mbstring

# Xdebug のインストール
RUN pecl install xdebug

# apacheのrewriteを有効にする
RUN a2enmod rewrite
COPY ./apache/sites-available/000-default.conf /etc/apache2/sites-available/

# php.ini への設定追加
ADD ./php/php-extention.ini /usr/local/etc/php/conf.d/

EXPOSE 80

RUN でコンテナ内のサーバーコマンドを実行することができます。

なので大体 RUN コマンドを使って CakePHP が動く環境や Xdebug のインストールのコマンドを定義していきます。

また、 PHP 公式の Docker イメージでは PHP の extension をインストールする便利コマンドが用意されてるようなので extension はそれらを使っていれていきます。

また、 ADDCOPY どちらもコンテナへのファイルの複製になりますが、細かい差などはよく分からないので検証してくれている方のリンクを貼っておきます。。

基本 ADD でいいのかなーと思ったり。

[docker] COPY とADD の違いを試してみた

Dockerfile でコンテナへコピーするファイルの作成

CakePHP で使う extension の設定や apache rewrite の有効化だったり、 Xdebug の設定を定義したファイルを作成します。

000-default.conf

<VirtualHost *:80>
    # The ServerName directive sets the request scheme, hostname and port that
    # the server uses to identify itself. This is used when creating
    # redirection URLs. In the context of virtual hosts, the ServerName
    # specifies what hostname must appear in the request's Host: header to
    # match this virtual host. For the default virtual host (this file) this
    # value is not decisive as it is used as a last resort host regardless.
    # However, you must set it for any further virtual host explicitly.
    #ServerName www.example.com

    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
    # error, crit, alert, emerg.
    # It is also possible to configure the loglevel for particular
    # modules, e.g.
    #LogLevel info ssl:warn

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # For most configuration files from conf-available/, which are
    # enabled or disabled at a global level, it is possible to
    # include a line for only one particular virtual host. For example the
    # following line enables the CGI configuration for this host only
    # after it has been globally disabled with "a2disconf".
    #Include conf-available/serve-cgi-bin.conf

  # 以下を追記しただけ
    <Directory /var/www/html>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    </Directory>
</VirtualHost>

コンテナ内の設定ファイルの内容をコピーして必要箇所を追記したファイルを作成しているだけです。

php-extention.ini

[Date]
date.timezone = "Asia/Tokyo"

[mbstring]
mbstring.internal_encoding = "UTF-8"
mbstring.language = "Japanese"

extension = "pdo_pgsql.so"

[xdebug]
zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20160303/xdebug.so
xdebug.coverage_enable=1
xdebug.default_enable=1
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp"
xdebug.remote_autostart=1
xdebug.remote_enable=1
xdebug.remote_host=ホスト名
xdebug.remote_port=9000

今回の仕様に合わせて php.ini に追記すべき内容を記載しているだけです。

docekr-compose up コマンドを実行してコンテナを起動

docker-compose up -d

これでめでたく PHP 公式の Docker イメージを利用した環境が構築できました。

めでたし。

最後に

色々ご教示してくださった会社の方々、ありがとうございました。

また、 Docker コンテナの web サーバーにある Xdebug と PhpStorm を連携させる方法は追々記事書こうと思います。。

取り急ぎ参考になったページ貼っときます。

PhpStorm + Docker for Mac(docker-compose)での PHPUnit と Remote Debug の設定 - Shin x Blog

PHP の HTTP Client ライブラリの Guzzle を使う

またまた、更新が遅れてしまいました。決まった感覚で記事あげるってやっぱり大変ですね。

この前会社の新卒から PHP で「 HTTP リクエスト送信するのって file_get_contents 使うしかないですかね〜?」と質問されました。

調べてみたら Guzzle という便利ライブラリがあったので、どんなもんかなぁと試してみました。

公式ドキュメント

Guzzle, PHP HTTP client — Guzzle Documentation

使い方

Composer でインストール

Composer でインストールしましょう。

composer require guzzlehttp/guzzle

インストールが終わったら、Composer が生成した autoload.php を↓みたいな感じで読み込んでおきましょう。

<?php

require __DIR__ . '/../vendor/autoload.php';

リクエストを送信する

ドキュメントを見ると、GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS はメソッドが用意されてるっぽい。

正直、使いたい HTTP メソッドは全部揃ってます。

あと、上記に加えて非同期でリクエストを送信する Async 版の各メソッドも用意されてます。(getAsync() など)大量のリクエストを送信したい場合や、一度の処理に複数の API を叩く必要がある場合は処理速度が上がったりして便利そう。

ちなみに、ライブラリの中身を見ると Async じゃない同期型のメソッドは request() が呼び出されていますが、最終的には requestAsync() を叩いてるっぽいです。非同期にならないように request() 内で制御かけてました。

適当に POST リクエスト送信します。

<?php

$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'リクエスト先URL', 'オプション');

これだけで HTTP リクエストが送信できて、レスポンスを取得できます。

オプションは公式ドキュメントを確認してください。

Request Options — Guzzle Documentation

フォームの値を送信したい場合なんかは form_params オプションを使えば良さそうですね。

Request Options form_params — Guzzle Documentation

最後に

大分端折って紹介しましたが、HTTP ステータスを取得できる getStatusCode() や、レスポンスヘッダーを取得する headers() メソッドもあるので、 file_get_contents() を駆使してリクエスト送るより使い勝手が良いですね。

HTTP リクエスト部分を Factory パターンで抽象化して作ってみました。

github.com