Reactを学びたいけど、どの書籍を買ったら良いか悩んでいる人向けのガイド

現在、(紙の)書籍として購入できる日本語の React の入門書の 良い点 / 残念な点 をまとめてみました。

なるべく公平な評価をしたつもりですが、私は 作りながら学ぶ React入門 の著者ですので若干のバイアスはご了承下さい。

結論

f:id:yuum3:20180109104730p:plain

作りながら学ぶ React入門

作りながら学ぶ React入門

作りながら学ぶ React入門

良い点

  • サポートページが充実している
  • 入門書として適度な分量
  • テスト(UnitTest, E2E test)の章がある

残念な点

  • Redux, mobX, flux 等の章がない(Reduxの紹介のみ)
  • Flow, TypeScriptの章がない(Flowの紹介のみ)

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

WebデベロッパーのためのReact開発入門 JavaScript UIライブラリの基本と活用

良い点

  • いち早く出版された
  • JSXの説明が丁寧

残念な点

  • PC/Macに環境を構築せずjsFiddleというSaasサービスを使う
  • ES5で書かれている
  • Reactが古く、だぶん最新のReactでは動かない

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発

良い点

  • 安心のオライリー品質
  • Reactの設計思想が詳しく解説されている
  • いち早く出版された

残念な点

  • ES5で書かれている
  • Reactが古く、だぶん最新のReactでは動かない

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

良い点

  • 安心のオライリー品質
  • 入門書としての完成度が高い
  • Fluxの章がある

残念な点

  • ほぼES5で書かれている
  • Reactが古く、だぶん最新のReactでは動かない

いまどきのJSプログラマーのための Node.jsとReactアプリケーション開発テクニック

良い点

  • React-Nativeの章がある
  • Electronの章がある
  • サーバーサイドのNode.jsの章がある

残念な点

  • いろいろなものを盛り込み過ぎで、やや深さが足りないかも
  • サポートページが弱い

2017年の振り返り

例年通り、今年も昨年2017年の仕事や個人を振り返ってみます。
まとめてみると、仕事をしっかりとやりながら、プライベートな活動が充実していた年でした。

f:id:yuum3:20180101002803j:plain

仕事

開発

昨年に引き続き React (+ Rails) のシステムもお客様が本格的に使い始め、いろいろな要望が現れ開発が続いています。jQueryからReactに移行しクライアントサイドはかなりすっきりしたのですが、今回の変更などでやや悪い香りのする部分が出てきています、これは今後の課題ですね。

後半に、ある方のアイデアを実現するためのシステム、iPhoneアプリRailsを作りました。久しぶりにiOSの開発はガッツリやってSwift力がやっと世間並みになった思います。

既存のお客様のシステムのメンテナンスも粛々と進めて行けました。

教育

例年どおりドリコムさんの新人教育に加え、いくつかの会社で「非開発者向けのプログラミング教育」を行いました。 通常のRails等の教育は少なかったです。

著作

Reactの教育を始めようと良いReactの書籍はないかと探していたのですがなかなか現れませんでした、そんな時にある出版社から Reactの本を書かないかとの問い合わせがありましたが色々あり、以前iPhone開発の本を書いた秀和システムからReact入門書 作りながら学ぶ React入門 を出版しました。まだそれほど売れてませんが React が広まるのはまだ時間がかかるかと思っていますので、この本の特徴である 充実したサポートページ を引き続きアップデートして行きたいと思います。

プライベート

TABICA

一昨年から参加しだした TABICA に頻繁に参加するようになりました。TABICAには色々なカテゴリーがありますが私が参加しているのは、ブラタモリ(初期の東京編)のような街歩きです。 スリバチ研究家階段研究家 の方と知ってるようで知らない街を歩くのは毎回発見があます。運動不足の解消にもつながり現在は月に1〜3回くらい参加しています。

TABICAの影響で、毎日お散歩もするようになりました。いつも歩いている街も色々な視点で見ながら歩いて行くのは楽しいです。

食い倒れ(美食?)系の知り合いが出来た

これも一昨年から @ogijun さんの会やそこで知り合った方と レストラン に行くようになりました。素晴らしい料理にふれる事の素晴らしさを再認識しています。

やはり、この影響で家族や個人で自由が丘を中心に新しく出来たお店や、まだ行った事のないお店に行くようになりました。昨年は家から30秒のところに ビストロ が出来たり、少し歩いたところに 良いレストラン が出来たりと楽しみが増えました。 一昨年、一時的に自由が丘を離れた体験から自由が丘の良さを見直したので、良いお店が自由が丘に増えてもらうには利用してお金を落とす事が重要だなと実感したので実践し始めました。

ワイン会に参加するようになった

少しづつワイン会にも参加し始めました。良く参加している ワイン店 のワイン会はあまり飲む機会のない産地のワインを知る事が出来、楽しみにしています。

美術展などに頻繁に行くようになった

若い頃から、美術には興味が高かったのですが、近年はあまり美術展などには行っていませんでしたが、今年はそこそこ行けたかなと思います。一昨年しりあった Apus さんの個展や会談会などに参加しました。

また、世田谷文学館で行われた「澁澤龍彦 ドラコニアの地平」点寺山修司の映画 など ノスタルジーにひたる様なイベントもあり、歳をとったなぁ〜と思うこともあるのでした。

「作りながら学ぶ React 入門」テストが終了しない問題が解決しました

「作りながら学ぶ React 入門」 の8章 テスティングでテストランナー mochaが 4.0.0 にアップデートしてから npm test が終了しない問題がありましたが、 mochaが 4.0.1 で解決されました。

ただし、 package.json にあるテストコマンドに --exit オプションを追加する必要があります、
詳しくはサポートページ https://github.com/yuumi3/react_book をご覧下さい。

f:id:yuum3:20171004095319p:plain

「作りながら学ぶ React 入門」 サポートページでは質問を受け付けています

「作りながら学ぶ React 入門」 サポートページ https://github.com/yuumi3/react_book では情報の提供以外に、質問などを受け付けています。

f:id:yuum3:20171004095319p:plain

サポートページでは

  • 開発環境の構築手順
  • 本に書かれている、ほぼ全てのコード
  • 正誤表
  • リンク

などのサポート情報が書かれていますが Issues で質問、ご意見、誤り情報などを受け付けています。 Issues に書くには GihHubアカウントが必要ですが、ニックネーム、メールアドレス、パスワードの登録だけで直ぐに使えますので、このさいGihHubアカウントを作ってしまいましょう!

質問等は IssuesNew issue ボタンを押して書いて下さい。私も出来る限りはやく返答しよう心がけています。

f:id:yuum3:20171004095300p:plain

Facebook等で頂いた感想は

  • モダンなJavaScript アプリの構成・開発環境が理解出来た (Angulaを使っている開発者の方より)
  • サポートページにコードがあるので、タイプミス等が無くコードが動かせる (デザイナー系の方より)

作りながら学ぶ React入門

作りながら学ぶ React入門

Reactの入門書を書きました「作りながら学ぶ React入門」、買って下さいね!

「作りながら学ぶ React入門」というReactの入門書を書きました。

Reactの情報は ReactのホームページDocs や中級者向けの入門 Tutorial にまとまっていますが、初心者には敷居が高いかもしれません。
私自身も Reactの教育を行うのに良い日本語書籍はないかなぁ? と探していたのですが見つからないので、自分で書くことにしました。

f:id:yuum3:20170904123837j:plain

「作りながら学ぶ React入門」の紹介

各章毎に作者の思いを込めつつ紹介記事を書きます

0. まえがき

原稿校正の最終段階で「まえがき」お願いいたします〜 と言われ、一般的な事を書いてもなぁ・・・と、とても悩みました。そこで素直に私とReactの関わりを書きました。
私自身が2万行のjQueryベースの ■■なSPAコードをReactに置き換えた経験が、この本には込められています。

1. はじめに

「前提知識」に書いているように本書は入門書ですが、「JavaScriptプログラミング入門」に付いては書かれていません。 既にJavaScript, jQuery等を使った事のある人を対象にしていますので注意して下さい。
ただし、今までの新人教育等の経験から判りやすさを心がけています。

既にReactを使いこなしてる方には、あまり役立つ情報は少ないかと思いますが、Reactに詳しくない同僚等に教えるのには役に立つと思います。

「Reactとは」は一般的な事を手短にまとめました。

重要な情報: サポートページ https://github.com/yuumi3/react_book

2. モダンJS開発環境の構築

本書ではMacまたはWindowsのターミナル(コマンドプロンプト)とエディターを使って開発するという(Web系)プログラマーとしては一般的なスタイルで進めています。そこでは避けて通れない開発環境の構築には力を入れてあります。

JavaScript関係の技術。開発ツールはとても進歩が早いですが、開発環境としてはここ数年で Webpack, Bable, ESLint などの開発ツールが主流になったのでこれらを使っています。

ただし、最初は開発の停滞していたnpmではなく yarn を使って書いていたのですがバタバタがあったり、突如 npm が進化したので npm に戻したりと振り回されました ^^);

今後の開発環境の進化は油断は出来ないので、後はサポートページで頑張ります

3. モダンJS開発環境の解説

本にも書きましたが、面倒な説明はいいから React を使いたい! という人は飛ばしても良いように、開発ツールの解説は別章にしました。

現在よく判らず開発ツールを使っている人にも、この章は役に立つかもしれませんね。

4. ES6

本書ではJavaScriptはES6(正確にはES2015)で書いています。この章ではある程度JavaScriptを知っている人に最低限必要なES6の説明をしています。

後半の「いろいろな補足」ではJavaScriptというかプログラミング言語の理解が深く無い人のために、オブジェクト指向、無名関数、イテレーターなのどの解説を書きました。Reactのプログラムではこれらが頻繁に使われるので、これらの判りにくい部分の理解に少しでも役に立つと良いなと思っています。

5. JSX

いよいよReactの解説です。JSXはReactの基本の基本ですJSXが書けないとReactは使えません。しかもJSXは従来のテンプレートエンジンとはいろいろと違います。
ということで、この章は力を入れて書いています。 例題(サンプルコード)は、ほぼHTML → 値を埋め込む → コンポーネント分割 → 条件・繰り返し と徐々に進化するように書いています。

デザイナーの方などはJSXを完璧に書けるようになれば、かなり仕事がはかどるのではないでしょうか?

6. コンポーネント

Reactの説明ですね、ライフサイクル・メソッドの図は頑張って書きました。

7. コンポーネントの応用

ここではMaterial-UIを使って美しい画面を作ったり、ルーティングを学んだり。 サーバーとの通信を学んだりします。ここは作って、動いたら楽しいような例題を取り上げたつもりです。

また、通信の部分では 非同期処理、Promise の解説などを行っています。

8. テスティング

テスティングに付いて書くかは迷ったのですが、昔からお世話になっている t-wada さんの顔が浮かんだので書きました。

E2Eテストに付いては ブラウザテストツール総まとめ・2016年夏版 記事に助けられました。テストツール(テストライブラリー)は多数ありますが、これだというものが無く、消去法的に Nightmare になりました。
これからは Headless Chrome を使ったツールか主流になるのかな・・・・

ちななみに、jQuery → React 置き換えの仕事では E2Eテストは Phantom.js + Turnip というRubyのツールを使いました

9. さらに学ぶなら

この本では取り上げなかった Redux, Flowtype, React Native, Electronに付いての簡単な説明を書きました。

そして、 Reactの情報源では英語の情報にアクセスしよう! ということを書きました。

作りながら学ぶ React入門

作りながら学ぶ React入門

AudioQueueを使って m4a (AAC) で録音する Swift 3.0 のサンプルコード

現在の仕事で作ってるiOSアプリの中に、マイクからの音をm4a (AAC) で録音する機能が必要なので、 適当なサンプルコードはネット上に在るだろうと思い探したのですが、案外みつかりませんでした。
なぜ見つからないかというと

  • 今回はいろいろな理由から、安易な AVFoundation ではなく AudioQueueを使う必要があった
  • Objective.c のサンプルは見つかるが、Swiftは少ない、さらに Swift 3.0 のコードは絶望的
  • また録音フォーマットが PCMのものばかり
  • オーディオ周りが好きなiOS(mac OS)プログラマーは少ないの?
  • 私もオーディオ周りの知識は極めて低い

f:id:yuum3:20170914161050p:plain

Google先生が教えてくれたのは以下でした

絶望の中、GitHubを検索するとAudioQueueTutorial という探していたものを見つけました。 Swift 3.0 です!
しかし、録音フォーマットは PCM ・・・・

そこで、いろいろ調べて少しずつ試しながら、遂に m4a(AAC) で録音できるサンプルが出来ました。完全なコードは AudioQueueTutorialのfork に置きました (m4aブランチ)。

変更か所は

録音フォーマットの設定

        info.mDataFormat.mFormatID = kAudioFormatMPEG4AAC
        info.mDataFormat.mSampleRate = 44100.0
        info.mDataFormat.mChannelsPerFrame = 2
        info.mDataFormat.mBitsPerChannel = 0
        info.mDataFormat.mFramesPerPacket = 1024
        info.mDataFormat.mBytesPerFrame = 0
        info.mDataFormat.mBytesPerPacket = 0
        info.mDataFormat.mFormatFlags = 0

バッファローサイズ計算の追加

    func DeriveBufferSize(seconds: Double) -> UInt32 {
        let maxBufferSize: UInt32 = 0x50000 // 320 KB

        var maxPacketSize: UInt32 = info.mDataFormat.mBytesPerPacket
        var outBufferSize: UInt32 = 0
        
        if maxPacketSize == 0 {
            var maxVBRPacketSize = UInt32(MemoryLayout<UInt32>.size)
            AudioQueueGetProperty (
                info.mQueue!,
                kAudioQueueProperty_MaximumOutputPacketSize,
                &maxPacketSize,
                &maxVBRPacketSize
            )
        }
        let numBytesForTime = info.mDataFormat.mSampleRate * Double(maxPacketSize) * seconds
        outBufferSize = numBytesForTime < Double(maxBufferSize) ? UInt32(numBytesForTime) : maxBufferSize
        return outBufferSize
    }

MagicCookie設定の追加

    func SetMagicCookieForFile() {
        var cookieSize = UInt32(MemoryLayout<UInt32>.size)
        
        var st = AudioQueueGetPropertySize(info.mQueue!,
                                          kAudioQueueProperty_MagicCookie,
                                          &cookieSize)
        if st == noErr {
            let magicCookie: UnsafeMutablePointer<CChar> = UnsafeMutablePointer<CChar>.allocate(capacity: Int(cookieSize))
            st = AudioQueueGetProperty(info.mQueue!,
                                 kAudioQueueProperty_MagicCookie,
                                 magicCookie,
                                 &cookieSize)
            if st != noErr {
                print("---- AudioQueueGetProperty error  \(st)")
                return
            }
            st = AudioFileSetProperty(info.mAudioFile!,
                                  kAudioFilePropertyMagicCookieData,
                                  cookieSize,
                                  magicCookie)
            magicCookie.deallocate(capacity: Int(cookieSize))
            if st != noErr {
                print("---- AudioFileSetProperty error  \(st)")
                return
            }
        } else {
            print("----  AudioQueueGetPropertySize error  \(st)")
        }
    }

ファイル作成、バッファー確保コードで上のメソッドを呼び出すようにした

        // create file
        let path = (NSTemporaryDirectory() as NSString).appendingPathComponent("audio.m4a")
        outputUrl = URL(fileURLWithPath: path)
        st = AudioFileCreateWithURL(outputUrl as CFURL, kAudioFileM4AType, &info.mDataFormat, .eraseFile, &info.mAudioFile)
        if st != noErr {
            print("---- AudioFileCreateWithURL error  \(st)")
            return nil
        }
        SetMagicCookieForFile()

        
        // allocate buffer
        info.bufferByteSize = DeriveBufferSize(seconds: 10.0)
        for _ in 0..<kNumberBuffers {
            var buffer: AudioQueueBufferRef?
            st = AudioQueueAllocateBuffer(queue!, info.bufferByteSize, &buffer)
            if st != noErr {
                print("---- AudioQueueAllocateBuffer error  \(st)")
                return nil
            }
            info.mBuffers.append(buffer!)
            AudioQueueEnqueueBuffer(queue!, buffer!, 0, nil)
        }

以上です、

tomisacat (tomisacat) · GitHub さんありがとうございます! それから参考にさえて頂いた情報を書いた人ありがとうございます。

いまさらながらAnsibleを使ってみた

世の中もうDockerの時代なのかもしれませんが、ある案件で使うサーバーのプロビジョニングツールとしてAnsibleを使ってみました。

f:id:yuum3:20170824145026p:plain

今まではChefを使っていましたがChefはRubyでガリガリ書けるので何でもできますが、メンテや構成管理情報を伝えるのに難があるかなと思ます。そこでシンプルという噂のAnsibleを使って、Ruby on Railsの動くサーバーを構築するAnsibleを書いてみました。

本家のドキュメント もちゃんとしてますし、ネット上にはたくさんの情報があるので楽に作れましたがそれでも何点か苦労したのでそこを中心に書きます。Playbooksは以下のようにroleに分けて書きました。

├── roles
│   ├── apps
│   │   ├── files
│   │   │   ├── logrotate
│   │   │   └── unicorn
│   │   └── tasks
│   │       └── main.yml
│   ├── linux
│   │   └── tasks
│   │       └── main.yml
│   ├── nginx
│   │   ├── files
│   │   │   └── logrotate
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── tasks
│   │   │   └── main.yml
│   │   └── templates
│   │       └── recorder.j2
│   ├── postgresql
│   │   └── tasks
│   │       └── main.yml
│   └── ruby
│       └── tasks
│           └── main.yml
└── site.yml

1. Linux(Unbuntu)の基本設定

てこずったのは、locale の設定。localeの作成やtimezoneの設定はmoduleがあるのに、locale設定は無いので update-locale コマンドを使いました。コマンドを使うと問題になるのが、どうやって冪等にするか。 update-locale は毎回実行されても問題はありませんが、Ansibleの勉強をかねて調べました。

ansible_env.LANGでターゲット側の環境変数が参照できます。ただしLANGが無い場合エラーになるのでデフォルト値を設定しました。

- name: install tools
  apt: name={{ item }} update_cache=yes
  with_items:
    - git
    - language-pack-ja

- name: create locale ja_JP.UTF-8
  locale_gen:
    name: ja_JP.UTF-8

- name: set locale to ja_JP.UTF-8
  command: update-locale LANG=ja_JP.UTF-8
  when: ansible_env.LANG | default('') != 'ja_JP.UTF-8'

- name: set timezone to Asia/Tokyo
  timezone:
    name: Asia/Tokyo

- name: install and start NTP
  apt: name=ntp

2. Rubyのインストール

これはネット上の情報で出来ました。Rubyのバーション番号等のパラメター(変数)は他の場所で定義した方が良いかもしれませんが、とりあえず同一ファイルに定義しました。

今回は /usr/local/binruby, gem … をインストールしたのですが、 gem module は user_install: no を設定しないと /usr/local/bin に入らないのでハマりました

- name:  define ruby version
  set_fact:
    workspace: /usr/local/src
    ruby_version: 2.4.1
    ruby_download_url: http://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.1.tar.gz

- name: install packages required to build ruby
  apt: "name={{ item }} state=present"
  with_items:
    - build-essential
    - zlib1g-dev
    - libssl-dev
    - libyaml-dev
    - libreadline6-dev
    - zlib1g-dev
    - libncurses5-dev
    - libffi-dev
    - libgdbm3
    - libgdbm-dev
    - libsqlite3-dev

- name: download ruby
  get_url:
    url: "{{ ruby_download_url }}"
    dest: "{{ workspace }}/ruby-{{ ruby_version }}.tar.gz"

- name: extract ruby
  unarchive:
    src: "{{ workspace }}/ruby-{{ ruby_version }}.tar.gz"
    dest: "{{ workspace }}/"
    copy: no

- name: build ruby
  command: >
    {{ item }}
    chdir={{ workspace }}/ruby-{{ ruby_version }}
    creates=/usr/local/bin/ruby
  with_items:
    - ./configure --disable-install-doc
    - make
    - make install
    - gem update --system

- name: install bundler gem
  gem:
    name: bundler
    user_install: no

3. PostgreSQL

PostgreSQLはUbuntu16.04標準の9.5ではなく、 9.6を入れたかったので apt_repository , apt_key を設定しました。
また、ログインアカウントでpsqlを使えるようにしたかったので pg_hba.conf を書き換えています。その後のPostgreSQL再起動はnotifyだと非同期になるので serviceで行いました。ここの冪等もAnsibleの勉強になりました ^^;

- name: add PostgreSQL repositories
  apt_repository:
    repo: deb http://apt.postgresql.org/pub/repos/apt/ xenial-pgdg main
    state: present

- name: add PostgreSQL key
  apt_key:
    url: https://www.postgresql.org/media/keys/ACCC4CF8.asc
    state: present

- name: install PostgreSQL
  apt: name={{ item }} update_cache=yes
  with_items:
    - postgresql-9.6
    - postgresql-client-9.6
    - postgresql-contrib-9.6
    - libpq-dev
    - python3-psycopg2

- name: configure PostgreSQL (authentication)
  replace:
    path: /etc/postgresql/9.6/main/pg_hba.conf
    regexp: '^local(\s.+?\s+)peer$'
    replace: 'local\1trust  # peer #'
  register: pg_hba_file

- name: restart PostgreSQL server
  service:
    name: postgresql
    state: restarted
  when: pg_hba_file.changed

- name: add user to PostgreSQL
  postgresql_user:
    name: XXXXXX
    password: XXXXXX
    role_attr_flags: CREATEDB,NOSUPERUSER

- name: add databases to PostgreSQL
  postgresql_db:
    name: XXXXXX
    owner: XXXXXX

4. Nginx

Nginx はネット上にあった情報でなんとかなりました

- name:  define nginx values
  set_fact:
    conf_file: /etc/nginx/sites-available/XXXXXX
    site_name: XXXXXX
    ssl: false
    unicorn_socket: unix:/tmp/unicorn.XXXXXX.socket
    public_path: /home/apps/XXXXXX/current/public

- name: install Nginx
  apt: name={{ item }} update_cache=yes
  with_items:
    - nginx
    - apache2-utils

- name: set this-site configuration
  template:
    src: ../templates/XXXXXX.j2
    dest: "{{ conf_file }}"
  notify: restart nginx

- name: disbale default configuration
  file:
    path: /etc/nginx/sites-enabled/default
    state: absent
  notify: restart nginx

- name: enable this-site configuration
  file:
    dest: /etc/nginx/sites-enabled/XXXXXX
    src:  "{{ conf_file }}"
    state: link
  notify: restart nginx

- name: set log rotation
  copy:
    src: ../files/logrotate
    dest: /etc/logrotate.d/nginx
    owner: root
    mode: 0644

5. アプリケーション

Ruby on Railsアプリケーション用の設定も簡単でした。ちなみにRails等のインストールはデプロイ時に行われるのでありません。

- name: make directory of application
  file:
    path: /home/apps/XXXXX
    state: directory
    owner: ubuntu
    group: ubuntu
    mode: 0755

- name: set unicorn configuration
  copy:
    src: ../files/unicorn
    dest: /etc/init.d/unicorn
    mode: 0755

- name: enable unicorn service
  service:
    name: unicorn
    enabled: yes
    use: service

- name: set log rotation
  copy:
    src: ../files/logrotate
    dest: /etc/logrotate.d/unicorn
    owner: root
    mode: 0644

感想

出来たplaybookを見るとChefに比べ短くシンプルですね。あまり難しい事をしないならAnsibleは楽です。ただし冪等を頑張ると少したいへんかも・・・・