コネヒト開発者ブログ

コネヒト開発者ブログ

社内で行うユーザーヒアリングの仕組みづくり

こんにちは、デザイナーのきよえし(@kiyoe_furuichi)です。

ママ向けサービスを運営する私たちは社内で働く約7割が子育て中のママさん・妊婦さんで、実際にユーザーとして日々サービスを使っていただいています。 そのため普段の会話から直接アイデアやフィードバックをいただいたりと、開発チームとユーザーの距離がとても近い環境です。

今回は、そんな私たちが社内で行っているユーザーヒアリングについてご紹介したいと思います。

f:id:connehito:20160425170355p:plain:w480

社内ヒアリングの課題

これまで行ってきた社内ヒアリングの方法として、質問・報告用のSlackチャンネル*1でご意見・ご要望を募ったり、ランチの際にラフにお聞きするといった方法でヒアリングさせていただいていたのですが、そんな中、このような声をいただくことがありました。

  • 業務中気になることがたまにあるけど、伝える前に忘れてしまう!
  • 細かすぎることだから伝えるまでもないかと思ってたけど実は…
  • 私だけが思ってることかもしれないから伝えなかったけどこうしてほしいと思ってた

もったいないですよね、まだまだ拾えていない声があることが分かります。 そこで、このような機会損失を減らせるようヒアリング方法の見直しを行い、開発チームとママさん方がもっと声を交換しやすくなる仕組みづくりにトライしました。


社内ヒアリングの改善

まず先ほどの声について詳しくヒアリングし、課題の洗い出しを行いました。

意見1. 業務中気になることがたまにあるけど、伝える前に忘れてしまう!

理由: 業務中の空き時間などに報告しようと思っているけれど、直近の業務に集中していると忘れてしまう。
仮説: 報告までの動線をもっと短くしてあげると、業務中でもぱっと思いついたことを投稿しやすくなるのではないか。

意見2. 細かすぎることだから伝えるまでもないかと思ってたけど実は…

理由: "すごく改善してほしいかと言われるとそうでもないこと"に関しては、報告してもいいのかな?と思い躊躇してしまう。
仮説: 小さなことでも報告していいような"気軽さ"がない。もっとラフにつぶやける場を用意すると良いのではないか。

意見3. 私だけが思ってることかもしれないから伝えなかったけどこうしてほしいと思ってた

理由: 自分の意見が正解なのかどうかが不安になり、何か思うことがあっても言いづらい。
仮説: 発言するハードルが高い。"誰"の意見といった情報はいらないのではないか。

また、開発チームからもご意見をいただきました。

  • 普段たくさんのご意見をいただいているため開発タスクの中に個々が埋もれてしまっている
  • ディスカッションしないと重要度が決めづらいものが多い
  • 複数から同じご意見をいただくことがあり、それぞれに説明するのが少し大変

これらの課題を解決するために必要なポイントを以下にまとめました。

  • 意見のしやすさ
  • 意見の管理のしやすさ
  • 開発タスクとしての落とし込みやすさ
  • 自分の意見で "サービスが良くなった" という実感のしやすさ

このポイントを考慮して作成したものがこちらのサイクルです。

f:id:connehito:20160429190654p:plain:w350

  1. 気になる報告 : 匿名フォームで報告を募る
  2. アンケート実施 : 報告内容の重要度を定量的に評価する
  3. 開発タスク化 : アンケートを基に開発タスクを作成する
  4. 実装・リリース : 改善内容を実装・リリースを行う
  5. 改善報告 : 改善報告をする

意見報告から開発リリースまで、開発チームとママさん方双方が気持ち良く参加できるサイクルになるよう工夫をしました。


ユーザーヒアリングサイクルの紹介

ここから各フェーズの具体的な内容についてご紹介していきます。

1.「気になる報告」フォームの設置

気軽に報告できるようにする施策として「気になる報告フォーム」*2を設置しました。

フォームは、個人としての意見を伝えるハードルを下げるために、匿名で投稿できるようにしました。 いただいた内容については開発の担当者に共有し、すぐに回答できるものは回答、検討が必要なものに関しては「改善進捗シート」にまとめます。これによって開発チームが意見の管理をしやすくなるのと、ママさん方も進捗の確認がしやすくなります。

f:id:connehito:20160425170941p:plain:w350

報告は改善進捗シートに記入する

進捗シートには報告それぞれに対応ラベルを記入して管理を行っています。 また記入する際は必ず、書いた人物が特定されないよう報告として届いた文言をそのまま流用しないように気をつけています。

  • 調査中 :不具合や懸念事項など、調査が必要な報告
  • 検討中 :改善前にアンケートをとる必要がある報告
  • 改善中 :開発タスク化されている、かつ実施予定日が決まっている報告
  • 改善完了 :リリースが完了し、「改善完了シート」に移動する対象の報告

f:id:connehito:20160425184116p:plain:w350

改善後は改善完了シートに記入する

改善完了した項目については「改善完了シート」で管理し、過去の改善の振り返りができるようにしました。

f:id:connehito:20160425171705p:plain:w350


2. 改善アンケートを実施

個々から挙がった「気になる報告」の内容は、どのくらいの方がその改善を望んでいるかどうかを定量的に判断する必要があります。そこで実施を検討するためのアンケートをこのフェーズで行います。

f:id:connehito:20160429233524p:plain:w350

主にアンケートで聞く内容については

  • その項目に対して気になることがあるかどうか
  • 具体的にどういったことが気になっているか

といったように、シンプルに感じたことを書いていただけるような内容にしています。こちらも匿名で投稿できるようになっています。

「改善進捗シート」の 検討中 ラベルの内容をアンケートし、以下の判断を行います。

  • 検討する : 結論が出なかったものは 検討中 フェーズを維持。項目に アンケート済み と記入する
  • 改善する : チームの共通課題として認められるものは、改善フェーズ 3. 開発タスクの作成 へ進める

アンケート結果が判断を決めかねるような結果だった場合、プロダクトオーナーを中心に開発チームでディスカッションを行い、必ず検討か改善どちらかに分けていきます。


3. 開発タスクを作成する

アンケート結果を基に開発タスクを作成します。優先度はプロダクトオーナーが判断し、実施予定日を決めていきます。 ここで開発チームが具体的な実装手順などの仕様を詰めていきます。


4. 実装・リリース

開発タスク化の実装予定日が決まった時点で、進捗シートのフェーズを 改善中 に変更し実装を行います。


5. 改善報告を行う

リリースの完了後、改善進捗シートから項目を削除し「改善完了シート」へ移動させます。 改善完了シートは1ヶ月ごとにまとめて全体へ改善報告を行います。

f:id:connehito:20160429180320p:plain:w350

以上が各フェーズについてのご紹介でした!


トライして分かったこと

f:id:connehito:20160429190654p:plain:w350

このサイクルを2週間回してみた結果、以下のようになりました。

改善結果

f:id:connehito:20160501193122p:plain:w350

改善前(Slackのチャンネルに投稿された報告数)

  • 報告数:17件
  • 改善数:10件

改善後(報告フォーム + Slackのチャンネルに投稿された報告数)

  • 報告数:45件
  • 改善数:13件

初めてまだ日が浅いので改善数は少ないですが、報告数が改善前に比べて約2.7倍という嬉しい結果となりました!

このサイクルの良いと思うところ

  • 社内全体で気軽に「サービスをより良くする」サイクルに参加できること
  • 今まで拾えなかった小さな課題を見つけることができること

気軽に参加できるようにすることで、社内全体でサービス向上を考えていくことできる良い施策だなと思います!
私個人も、報告フォームからいただくご意見の中でハッとさせられるような気づきが多く、日々学びがあります。

現状の課題

  • 業務中は基本的にSlackを見る時間が限られるため、 業務中気になることがたまにあるけど、伝える前に忘れてしまう といった問題がまだ解決されていません。この対策として、ママさん方が日頃触るコンテンツ内にリンクを設置する案を考えています。


最後に

ここまで読んでいただき、ありがとうございました! まだまだ改善中なので今後も試行錯誤しながら取り組んでいきます。

以上、デザイナーのきよえし(@kiyoe_furuichi)でした!

*1:ママさん方も業務中のコミュニケーションツールとしてSlackを利用しており、業務中に困ったことや気づきがあった際にこちらのチャンネルに投稿があったものを、開発チームなどが都度対応しています。

*2:こちらのフォームはクックパッド開発者ブログさんの「品質の向上に対する取り組み」を参考にさせていただきました。

やさしいPHPコーディング規約の導入・完全版

f:id:fortkle:20160417190347p:plain

はじめに

こんにちは、社内でコーディング規約おじさんと呼ばれ始めて久しい高野(@fortkle)です! ここ2ヶ月間ほどに渡って通常の開発業務とは別に社内のアプリケーションにコーディング規約を導入する試みをしており、PHP7 Casual Talks や PHP BLT などのPHP関連の勉強会で都度共有してきました。

今回はそれらをまとめ、共有したいと思います。興味のある方の参考になれば幸いです。

続きを読む

ESLintを途中で導入したときの.eslintrcの設定と運用方法について考えた

f:id:dachi023:20160401044514j:plain

こんにちは。花粉症に悩まされているエンジニアの安達(@ry0_adachi)です。

前回は運用中のサービスへのwebpackの導入についてお話しさせていただきましたが、今回はESLintの導入と運用方法について話していきたいと思います。

Linterを途中から導入したときの課題

複数人の開発メンバーがいる状況下でLinterがあるとコードの書き方が統一できたり、定義忘れなどでの不要なエラーを未然に防ぐことができます。
便利なツールなのでプロジェクトの途中からでも入れたい!と思う方は少なくないかと思いますが、その際に高確率で発生する問題があります。

既存のコードでエラーが出る

全く出ないということはほぼ無いかな、と。行末にスペースが紛れてしまったりとか気をつけていてもたまにやってしまったりします。
そんなわけでLinterを途中から導入した際に発生したエラーとどう向き合って、今後エラーを無くしていくためにどう運用していくかを考えることにしました。

ESLintとは

今回導入したのはESLintというJavaScriptのコードの書き方をチェックするためのLinterです。
主にインデントのズレ、未定義 or 未使用の変数がある、セミコロンが無い、などを検知して警告やエラーを出してくれます。

どんなプロジェクトにも合わせられる

大げさかもしれませんが、割と本当です。それくらいESLintは柔軟です。

  • ルールはそれぞれ独立しているので個別に設定することが可能
    • on/offが選択できる
    • 警告 or エラーを選択できる
  • 独自ルールを定義できる
  • 標準で多くのルールがある
    • 標準のルールだけでも十分にLinterとしての威力を発揮してくれます
  • プラグインが豊富
    • 各種フレームワークにも対応できる

JSHintなどの他のLinterとの大きな違いとしては独自にルールを作成でき、プラグインとして追加できることです。
これによって柔軟性が大幅に高まり、独自ルールがあるような場合にも合わせることが可能になっています。

運用方法を考えて実践する

1. とりあえずrecommendedだけ

ESLintには推奨の設定が用意してあります。.eslintrcに下記のように定義します。

envは該当の環境で定義される変数を自動で定義済みである状態にしてくれます。browserならdocumentとかですね。それによって未定義の変数でエラー、とならなくなります。
browserifywebpackを使用している場合はcommonjsもtrueにしておきます。

まずはrecommendedで怒られるエラーだけを直していくのが良いと思います。
その後ルールを後追いで追加して、という形にした方がエラーの修正にかかる時間を分散できるから。という理由です。

2. 見つけたら直してもらう

プロダクトコードの修正などで実装する箇所でエラーが出ていたらついでに直してもらうようメンバーにお願いします。そうすることでプロダクトの開発をしながらでもエラーの数も減っていき、少しずつコードも綺麗になっていきます。

機能やコンポーネントごとにファイルが綺麗に分割されているのであれば触ったファイルの全てのエラーを直す、というやり方が可能です(きっと1ファイル数十行、とかなので)。
もしそういったやり方が少し難しいな、と感じたら関数ごとに直していく、など一度で直す範囲を狭めるのがライトでいいんじゃないかなと思います。

コネヒトでは事前にファイルを分割するというリファクタリングを行っており、短いコードが多いので、もしエラーがあればファイルごとに直すようにしています。

3. 足りなければルールを追加する

もし必要なルールが増えた場合は追加します。
例としてセミコロンがないとエラーになるようにしてみましょう。

これでセミコロンを忘れた場合に怒られるようになりました。そしてこれを「ここまでやれば十分!!」となるまで繰り返します。
一度追加したルールはその後も怒られる対象なのでせっかく直したのにまたエラー...ということはないでしょう。

4. 綺麗なコードを目指して

後は2と3を繰り返していくだけです。
最後まで頑張るのが何よりも大事ですので根気よく続けていきましょう。

まとめ

  • Linterをプロジェクトの途中から導入すると既存のコードでエラーが発生しやすい
  • ESLintは柔軟性が高く様々なプロジェクト、プロダクトに対応するための設定が可能
  • まずはrecommendedのエラーを消すところから始めて、直し終わったらルールを足す→エラーを消す、を繰り返す

余談ですが、最初から導入できるのであればそちらの方がいいですよ!!

最後に

いかがでしたでしょうか?ドキュメントだけではなかなか運用が難しいコーディング規約もツールで自動チェックができるようになります。簡単に導入できるのでまだ入れていない方はぜひこれを機にチャレンジしてみてください。

fastlaneとTravisでいい感じのタイミングでアプリを受け取る

お久しぶりです、3/31, 4/1は仕事ですが、4/2はバルト9へ行く田村(@Utmrer)です。 今回は弊社でのfastlaneによるアプリ配布についてお話します。

アプリ配布の通知メールの回数を減らしたい

開発段階のアプリを社内やテスターに配布する処理を何かしらのScriptで書いてCIで実行し、自動化している人は多いかと思います。 弊社も一時期配布を自動化していましたが、2つの問題がありました。

  1. RC, AdHoc, Development等、複数の環境のビルドが必要である
  2. PushしてCIが回るだびに通知メールがくると煩わしい

という感じで毎回複数環境のBuildを実行するのは時間が掛かり過ぎる、メールを送ってアップデートを促したいが「頻繁にメールが来ることによって、メールを無視することが普通になる」とアップデートしてもらえない、と問題を抱えていたので都度手動で配布してましたが、「fastlaneが便利らしいぞ」という話を聞いたので、Travisで自動化することにしました。

証明書をリポジトリに含める

Travis上でアプリをビルドするために証明書を書き出します。 f:id:Utmrer:20160320223115p:plain キーチェーンからiPhone Distribution: Your Name (Team ID)、そして今回はDevelopmentのBuildも配布するのでiPhone Developer: Your Name (Team ID)p12を書き出します。 WWDRCAはTravisなら最初から入ってます。

各環境のlane等をFastfileに定義する

最終目的なFastfileはこんな感じになります。

fastlane_version "1.61.0"

default_platform :ios

platform :ios do
  before_all do
    ENV['KEYCHAIN_NAME'] = "TempKeychain.keychain"
  end

  desc "Build for AdHoc"
  lane :build_adhoc do
    sigh(
      app_identifier: "com.example.app.adhoc",
      adhoc: true,
      skip_certificate_verification: true,
    )
    ENV["PROFILE_UDID"] = lane_context[SharedValues::SIGH_UDID]
    gym(
      clean: true,
      workspace: "App.xcworkspace",
      scheme: "Adhoc",
      use_legacy_build_api: true
    )
    deploy_crashlytics
  end

  desc "Build for Debug"
  lane :build_debug do
    sigh(
      app_identifier: "com.example.app.dev",
      development: true,
      provisioning_name: "Debug",
      skip_certificate_verification: true
    )
    ENV["PROFILE_UDID"] = lane_context[SharedValues::SIGH_UDID]
    gym(
      clean: true,
      workspace: "App.xcworkspace",
      scheme: "Debug",
      use_legacy_build_api: true
    )
    deploy_crashlytics
  end

  desc "Build for Release"
  lane :build_release do
    sigh(
      app_identifier: "com.example.app",
      adhoc: false,
      provisioning_name: "Release",
    )
    ENV["PROFILE_UDID"] = lane_context[SharedValues::SIGH_UDID]
    gym(
      clean: true,
      workspace: "App.xcworkspace",
      scheme: "Release",
      use_legacy_build_api: true
    )
    deliver(
      force: true,
      skip_screenshots: true,
      skip_metadata: true
    )
  end

  desc "Import Certificates"
  lane :import_certificates do
    return unless Helper.is_ci?

    create_keychain(
      name: ENV["KEYCHAIN_NAME"],
      default_keychain: true,
      unlock: true,
      timeout: 3600,
      lock_when_sleeps: true,
      password: ENV["PASSWORD"]
    )

    import_certificate(
      certificate_path: "./certificates/distribution.p12",
      certificate_password: ENV['PASSWORD'],
      keychain_name: ENV["KEYCHAIN_NAME"]
    )

    import_certificate(
      certificate_path: "./certificates/development.p12",
      certificate_password: ENV['PASSWORD'],
      keychain_name: ENV["KEYCHAIN_NAME"]
    )
  end

  after_all do |lane|
  end

  error do |lane, exception|
  end

  def deploy_crashlytics
    crashlytics(
      api_token: "YOUR_API_TOKEN",
      build_secret: "YOUR_BUILD_SECRET",
      groups: 'tester_group',
      notifications: true
    )
  end

end

build_adhoc/build_debug/build_releaseがそれぞれの環境別のBuildを作成し、Crashlyticsへアップロードするlaneです。
ENV['PASSWORD']は「ちょっとパスワードとかcommitに含めるの嫌だなぁ〜」って時に、コマンドで暗号化して.travis.ymlで定義した環境変数です。
fastlaneでiOS Dev CenterやiTune Connectに接続するために必要なFASTLANE_USERFASTLANE_PASSWORDと合わせてこのようなコマンドで暗号化します。
travis encrypt PASSWORD=CERT_PASSWORD FASTLANE_USER=APPLE_EMAIL FASTLANE_PASSWORD=APPLE_PASSWORD
詳しくはこちらをご覧ください。
Encryption keys - Travis CI

ちょっとハマったところはprovisioning_nameを指定するところです。ここでprovisioning_nameを指定しないと、新しいProvisioning Profileを次々に生成し、iOS Dev Centerがかなりカオスになりました。

Travisでいい感じのタイミングでBuildする

f:id:Utmrer:20160321115901p:plain さて、それぞれの環境のlaneが出来たので、それぞれをいい感じのタイミングで実行しましょう。
弊社のiOSプロジェクトはgit-flowで開発しており、新しい機能はfeaturebranchを作り、実装が終わるとdevelopbranchへmerge、リリースのタイミングになるとそこからreleasebranchを作って全体的な機能の確認をし、問題が無ければmaterへmergeされるというflowをとっています。

  1. 新しい機能の実装が一旦完了した段階でみんなに開発環境アプリをインストールしてもらいたい
  2. 新しいリリースを申請する段階でみんなにAdHoc環境アプリをインストールしてもらいたい

という2つのタイミングがアプリを配布したいタイミングなので「featurebranchをdevelopbranchへmergeしたタイミングで開発環境アプリ」「masterbranchへreleasebranchをmergeしたタイミングでAdHoc環境アプリ」を配布することにしました。あとmasterへmergeされたタイミングでiTunesConnectにもアップロードしちゃいましょう。
その仕様を満たす.travis.ymlはこんな感じになりました。

language: objective-c
osx_image: xcode7.2
env:
  global:
  - LANG=en_US.UTF-8
  - LC_ALL=en_US.UTF-8
  - secure: COMMAND_DE_ANGO_KA_SHITA_PASSWORD_TOKA
script:
  # YOUR_TEST_SCRIPT
after_success:
  # Deploy Release/AdHoc App
  - "[[ $TRAVIS_PULL_REQUEST == 'false' ]] && [[ $TRAVIS_BRANCH == 'master' ]] && fastlane import_certificates && fastlane build_release && fastlane build_adhoc"
  # Deploy Debug App
  - "[[ $TRAVIS_PULL_REQUEST == 'false' ]] && [[ $TRAVIS_BRANCH == 'develop' ]] && fastlane import_certificates && fastlane build_debug"

本当はDeploymentを使ってDeployしたかったのですが、Deploymentではうまくfastlaneが動かなかったのでafter_successで実行しています。
$TRAVIS_PULL_REQUESTの判定でPushした時だけ実行するようにし、$TRAVIS_BRANCHの判定で特定のbranchでlaneを実行するようにしています。
ここの処理はもうちょっと綺麗に出来そうですね、Circle CIならもうちょっと綺麗だった気がします。
これでdevelopへmergeした時に開発環境アプリが、masterへmergeした時にAdHoc環境アプリがテスターに届くようになりました!

おわりに

この機能の実装に50 commit以上かかってしまって、完成した時の達成感がかなり大きかったです!(証明書辛い…)
fastlaneは社内でテスター募集をする時にboardingを使ったりしてるのですが、もうちょっと色々触ってみたいですね。(dg add-devices的なのをSlackからやったり)
それと今回はCrashlyticsから新しいアプリがメールで行きますが、出来ればSlackに何かしら通知したいですね。弊社の人はメールクライアントよりSlackにいる時間が長いのでSlackに通知した方がアップデートしてくれそうです。
もっと良い配布方法や.travis.ymlの書き方をご存じの方は是非教えて下さい!ではでは👋

実践してみてわかった、ビジネスチームと一緒に「技術で勝つ」チームを創る3つの方法

f:id:tatsushim:20160303174817j:plain

こんにちは

CTOの島田(@tatsushim)です。 今回はビジネスチームのメンバーと一緒に「技術で勝つ」チームをどう創るかという点についてご紹介させていただければと思います。

勝ちたい!

突然ですが、Webサービスを創るからにはそのサービスをNo.1のサービスにしたいと思っています。しかし数の勝負では大企業に勝てません。
日本の3人に1人のママが利用するmamari事業を支えているのはたった11名の社員です(2016年3月4日現在)。 少数精鋭で戦うために、弊社ではビジネスチームにも積極的に技術を使ってもらっています。 技術を使ってもらうメリットには以下のようなものがあります。

  • エンジニアとコミュニケーションしやすくなる
  • ビジネスissueからの要求でエンジニアのリソースを取ることが減る
  • 全員が「技術」で解決しようという思考になる

以下、実際に私達が今実践している3つの工夫について、解説していきます。

「技術で勝つ」チームを創る3つの方法

1.タスクリスト(issue)はGitHubで一元管理する

実は弊社は開発だけでなく営業のようなビジネスissueもGitHub上で管理しています。
具体的には

リポジトリ名 用途
Sales 営業系の案件管理や情報共有
Review 行った施策の振り返り
Direction サービス全体のディレクションや組織運営に関わること

というリポジトリが存在しています。 それらをGitHubにすることで以下のような恩恵がありました。

  • GitHub管理下なので、関連する開発issueにメンション(ref.)を飛ばしやすい
  • Assigneeを利用することで「誰がボールを持っているのか」を視覚化することができる
  • チャット(Slack)上で流れてしまっていたログをGitHubに記録として残すことができる

2.GitHubとSlackとの連携を密にする

GitHubに統一すると上記のようなメリットがある一方、人によっては少し慣れない部分もあると思います。 弊社ではHubotを通してGitHubへのアクセスをSlackベースにすることでそのハードルを下げています。

f:id:tatsushim:20160303175640p:plain

上記の例はcreate issue [リポジトリ名] issueのタイトルというコマンドでissueを作成し、そのissueに対してSlack経由でコメントしています。

3.SQLリストを作って共有する

f:id:tatsushim:20160304150645p:plain

メンバー全員にDBのリード権限を与えてデータを自由に見てもらっています。 そして一度「この集計データがみたい」というリクエストをもらったらそのSQLをエンジニアが書いて、それを用途別にGoogleSpreadSheet等にまとめています。 それらを参照しつつ、コピペして実行するだけでも「こんなデータが見れるんだ!」という体験がSQLへの関心を高めてくれています。

その結果今では自分でSQLを書き、Google BigQueryからデータを取り出して、エンジニアの手を借りず仮説検証を一人で回すメンバーも出てきました。

以上をやってみて、感じた変化

f:id:tatsushim:20160304161554j:plain

弊社のKPT MTG*1はフルタイムのメンバー全員で行っているのですが、 技術の話題を出してもスムーズに良いディスカッションができています。 その結果、問題点に対してエンジニアの枠内で最適化するのではなく、会社全体の問題として捉え解決に向けて取り組むことができていると思います。

おわりに

最後まで読んでいただき有難うございました。 今回触れたトピックについてより良い方法やご意見がある方は、はてぶコメントやTwitter等でいただけますと嬉しいです。

*1:KPTとはKeep/Problem/Tryの頭文字をとった、振り返りの為のフレームワークです

webpackを運用中のサービスに素早く導入する

f:id:dachi023:20160218152829j:plain

はじめまして!

2月から入社したエンジニアの安達(@ry0_adachi)です。

私からはwebpackを導入する際に行ったことをご紹介していきます。
webpackに乗り換えることのメリットって何だろう?という方や、運用中のサービスがGruntやgulp、browserifyで近いうちにwebpackに乗り換えたいなぁ、と考えている方の参考になれば幸いです。

webpackとは?

ざっくり言うと「コード間の依存を解決するためのツール及びビルドツール」です。
AはBに依存している、といった状態の時にAの書かれているファイルに対してBのファイルを結合して参照できるようにするのがwebpackの仕事です。

なぜwebpackなのか

なぜ私がwebpackを導入しようと思ったか、についてですが2つ大きな理由があります。

モジュールロードシステムの導入

ファイルを跨いだモジュールの呼び出しを行うための仕組みは他の言語では初めから当たり前のように実装されている機能ですが、残念なことにJavascriptに追加されたのは最近になってからのことです。
ES2015からはimport/exportが使えるようになっていますが、現在Connehitoで運用しているサービスのコードはES5で実装されています。
そこでwebpackを利用することでWebアプリでもモジュールロードを可能にして依存性を自動で解決しよう!と考えました。

複数のファイルをまとめて出力したい

browserifyというwebpackに似たツールがありますが、こちらは1回のビルドで1つのファイルしか出力できません。
今回は複数のファイルを出力したかったこともあり、複数ファイルの出力が可能なwebpackを選びました。

現状を理解する

webpackに限ったことではありませんが、既存のサービスに対して手を加える場合、どのような作りで何をしているのか、を理解している必要があります。
まずは手を動かすよりも先にコードをしっかりと読むことにしました。

コードを読んで分かったこと

  • CommonJS, AMDに対応していない
  • 外部ライブラリはパッケージ管理をしていない
  • gulpでファイルを結合して圧縮をかけている

上記がwebpackを導入する前の状態でした。
また、既に運用中であることや、まずは導入してから徐々にwebpackで管理する領域を広げていこうという思惑もあったので、今回は Javascriptをwebpackでビルドする ことをゴールにします。

今回やること

  • CommonJSに対応させる
  • ライブラリをnpmでパッケージ管理する
  • webpackでファイルを結合して圧縮をかける

いざ、webpack

それでは導入にあたって行ったことを順を追って説明していきます。

1. CommonJSに対応させる

CommonJSというのはJavascriptの標準APIの仕様を策定している文書、プロジェクトのことです。
その中でモジュールのロードはrequireとexportsでやりますよ、と定義されています。
そして、これはES2015のimportとexportに非常に似ています。そんなこともあり今後ES2015に書き直した時に修正が簡単なようにCommonJSのモジュールロードの仕様に対応することにしました。
やったことは となっているコードを とするだけです。非常に簡単ですね!
これだけ?と思われるかもしれませんが、これだけです。モジュールロード最高ですね。
この作業をファイルの数だけ繰り返してmodule.exportsに既存のコードを詰め込んでいきました。
module.exportsを書いたコードはrequireを使うことで呼び出せるようになります。

2. ライブラリをパッケージ管理する

使っているライブラリも一緒にrequireしたいのでnpmで管理することにしました。
ConnehitoではBackbone.jsを採用しているのでnpm経由でインストールしてみます。

# 依存するunderscore.jsも一緒に入れます
$ npm install --save underscore backbone

インストールが無事終わったらrequireを使って呼び出すコードを書きます。 これでBackbone.jsとunderscore.jsが使えるようになりました。
他にも使用しているライブラリがいくつかあったのですが、そちらも同様にnpmで入れ直してrequireする、とするだけでした。 本当に良い時代です。これでライブラリがパッケージ管理されるようになり、簡単にrequireもできるようになりました。

3. webpackでファイルを結合して圧縮をかける

いよいよgulpのビルドタスクをwebpackへ移行します。
とりあえずwebpackをインストール。

$ npm install -g webpack

ファイルの結合に関してはbrowserifyのように依存解決と一緒にやってくれるので特にやることはありません。
というわけで、基本的な設定と圧縮するための設定を用意してあげます。 圧縮するだけならこれだけでOKです!短くていいですね!
そして、ついに実行する時がきました!webpackコマンドを叩いてみましょう!

$ webpack

2つのビルドされたJavascriptファイル(bundle-hello.js、bundle-backbone.js)とそれぞれのソースマップが無事生成されてwebpack移行第1弾が完了です!
他にもファイル監視やES2015のトランスパイルなど、webpackにやってもらいたい仕事がたくさん残っているので第2弾も現在計画中です...!

まとめ

Javascriptをビルドするだけ、という形で導入してみました。
今回はサンプルコードでのご紹介だったので直したのは一箇所でしたが、実際はexportsをサービス全体に埋め込んでいったので、今はどこからでもrequireで使いたい機能が呼び出せちゃいます。
初めから全てを移行するのではなく少しずつ移行することで敷居も下がって導入しやすいので非常にオススメな方法です!!


webpackとES2015を使ってJavascriptを書きたい!
そんなフロント好きなエンジニアの方はConnehitoへ遊びに来て私と今後のモダンなフロントについて語り合いましょう!

www.wantedly.com

PHP7にCakePHP2.xが来るぞ!!!!!

f:id:connehito:20160205104322j:plain

来るぞ!!!

ご無沙汰しております。
コネヒトでPHPを書いている金城 / @o0h_です。
タイトルの通りですが、CakePHP 2.xが次期バージョンの2.8でPHP7に対応!(!)という話を小耳に挟んだので、喰いついてみました。

PHP7 Compatibility!!!

f:id:connehito:20160204202829p:plain

CakePHP、PHP5時代と次世代への断絶

新しい世界・・・・怖いのかな・・・めちゃくちゃ大変なの??
という事には、(実際に使うかは別としても)興味を持つ人も多いのではないかな!!!と思いました。
かくいう私もその1人、さればとGithubを眺めながら「何が起きたか」を探って参りました。
CakePHPが通った道のりを紐解くことで、「PHP7に飛び乗るための覚悟」を少し育めたらなと思います。

続きを読む