Photoruction工事中!

Photoructionの開発ブログです!

PMの私がチームとの向き合い方で大切にしていること

はじめに

株式会社フォトラクションでプロダクトマネージャー(PM)をしています千葉由孝と申します。

Photoruction Advent Calendar 2021の11日目の記事です。 私は、非IT企業から転職して開発経験もないままPMを任されました。その後、まもなく新規サービスの立ち上げに携わることになります。そんな怒涛のような経験の中で、プロジェクトで発生する問題の向き合い方やチームメンバーとの向き合い方がチームを構築する上で特に大切だと感じました。自分の経験と学んだことを整理して書いてみましたので何かの参考になったらうれしいです。

 

自己紹介


少し私の自己紹介をします。私は前職で、事務所ビルやマンションなどの大型物件の施工管理を担当していました。いわゆる現場監督です。

突然ですが、建設現場で働く職人さんはめちゃめちゃかっこいいのって知っていますか?

自分たちが作ったものに対するプロ意識が非常に高く、使う人のことをいつも考えています。その妥協しない仕事振りはとても魅力的でした。こういう人たちが日本の建設業を支えていると思うととても誇らしい気持ちになります。また、建設業は建物や道路など生活の基盤を作る重要な産業です。

魅力がたくさんある一方で、現場監督の仕事は書類と格闘する長時間労働の日々でした。紙図面を持ち歩き、毎日現場で検査を行ったりと、職人さんが帰ってから夜遅くまで大量の書類作成に追われます。そんな日々を過ごすうちに、建設業で働く人々をもっと楽にする方法はないのかと考えるようになりました。そして、現場で培った経験を活かしかゆいところに手が届くプロダクトを作りたいという思いで転職しました。

建設業のことばかり書いてしまいましたが、私はそんな建設業が大好き人間です。この情熱でPMとして今日まで活動してきました。

 

チームを構築するために大切にしていること


私は、建設業のドメイン知識は自信がありましたが、それだけでは良いプロダクトを作ることはできません。PMの仕事はビジネス、テクノロジー、UXの領域が必要になります。ですがこの広い領域のスキルを一朝一夕で身に着けることは当然ながら難しい。そのため、スキルや知識がある人に協力を得たり、スキルを補完し合う関係性をチームで構築していくことが大切になります。

そのために私が意識していることは以下の2点です。

1.問題が発生したら自分ごと化してチームメンバーに共感し行動する

2.相手との目線合わせや役割の理解を大切にする

 

1.問題が発生したら自分ごと化してチームメンバーに共感し行動する


どのプロジェクトもそうだと思いますが、進めていく中で、大なり小なり様々な問題が発生します。チームの問題を解決に導くのもPMの役割です。私は、チームメンバーが直面する問題を人任せにせず、自分の問題として捉え、当事者意識も持つようにしています。

その上で、対応するメンバーの置かれた状況や気持ちを理解するところから行動を起こすようにしています。自分で解決できそうなら静観して見守ります。困っていたら一緒に手伝います。もしくは他のメンバーを巻き込みチームで解決するように支援をします。メンバーの気持ちに共感し、その人が力を発揮しやすい解決策を考えることも大切だと思います。

この大切さに気づいたのは、あるプロジェクトで起きた出来事がきっかけでした。担当エンジニアは実装方法について悩んでいたのですが、自分の領域外だと思い、エンジニアに任せっきりにしてしまいました。エンジニアは課題を抱えたまま、時間が経ち、リリースの延期など大きな問題に発展することになりました。私の当事者意識が欠けていたことが、課題の放置に繋がってしまったのだと思います。

 

2.相手との目線合わせや役割の理解を大切にする


PMの仕事は開発からビジネス領域まで多岐にわたるので、他部署の人と会話や議論をする機会が多くあります。私が意識しているのは、その人がどういう目線でプロダクトについて話しているのかを理解することです。

時には、さらに進んでその人の思考のプロセスをトレースするくらいその部署の人になりきることを意識しています。少し過剰かもしれませんが、それくらい意識しないと他人を理解することが難しいからです。

例えば、営業の人であれば、どういう伝え方が顧客に刺さるのか、顧客の業務がどのくらい改善されるのか、競合他社との違いや優位性は何なのかといったことを考えているかもしれません。

エンジニアであれば、実装する機能を顧客がどのように使ってくれるのか、実装にモダンな技術が使われているのかといったことを考えているかもしれません。(あくまで一例なのでみんなそうというわけでなく、目線が違うということが伝わればありがたいです。)

また、その人を理解するには、どんな業務をやっているのか役割を理解することも大切です。

以前は、他部署の方と話すときになかなか理解してもらえず苦労していたことが多かったですが、相手の役割や目線の理解し、準備をしっかりして相手目線で話すことで、共通理解を作りやすくなったと感じています。

 

まとめ


PMになって1年半余りの経験を通して、プロジェクトの問題の向き合い方、チームメンバーや関係者との向き合い方について記載しました。

不確実なプロダクト開発の中で、日々起こる問題を乗り越えていけるチーム作りが必要ですし、そのためには、関係者の協力を集め、必要なスキルを補完し合う関係性を構築していくことが大切だと感じています。

これからも建設業で働く人々に役立つプロダクト作りに邁進していきます。

読んでいただきありがとうございました!

 

 

株式会社フォトラクションでは一緒に働く仲間を募集していますhttps://corporate.photoruction.com/careers/ https://www.wantedly.com/companies/photoruction/projects

カスタマーサクセス・サポートを経験したプロダクトマネージャーの強みと苦労について

こんにちは!株式会社フォトラクションでPMグループリーダーをしている市橋です。 Photoruction Advent Calendar 2021の10日目の記事です。

本記事では、カスタマーサクセス(CSM・サポート)を経てプロダクトマネージャー(PM・PdM)にキャリアチェンジした私が考える、ユーザーに近いポジションからプロダクトマネージャーになったことによる強みと苦労している点ついて簡単にまとめています。

同じようにカスタマーサクセスやカスタマーサポート(以降、CSとします)または他の職種から、プロダクトマネージャー(以降、PMとします)へのキャリアチェンジを考えている方の参考になれば嬉しいです。

目次

私の簡単な経歴


私は建築系の学科を卒業後、大手建設コンサルタント企業で道路設計をしていました。

建設業界は労働人口が減少しており、今後さらなる生産性や魅力の向上が求められています。

そんな中、「建設の世界を限りなくスマートにする」というミッションを掲げてアプローチしている弊社で、業界で働く人達がスマートに働けるようにサポートしたいと思い、2019年末にCSMの立ち上げメンバーとして入社しました。

フォトラクションのCS


フォトラクションのCSは、photoructionを導入いただいている企業の方が、よりphotoructionを使いこなしていただけるために、以下のようなことをしています。

  • 導入いただいた企業様への操作説明会の実施
  • 各企業様との月次定例会を開催し、利用状況の確認や今後より活用できるようにするためのアクションプランの策定
  • 利用状況を計測し、使えている方・使えていない方それぞれの要因分析
  • 問い合わせ対応・サポートサイトの作成

PMへのキャリアチェンジを考えたきっかけ


日々photoructionをご利用いただいている方と接していく中で、「こんなことができなくて困ってるんだよね」や「この部分が使いづらいんだよね〜」と言ったご意見を聞いていくうちに、

「こんな機能だったら使いやすいのに」「自分だったらどうやって改良していくだろう」という考えを抱くようになっていきました。

もともと、ものづくりが好きだった(学生自体は建築の模型づくりが好きだったり、自宅の家具をDIYしたり、プログラミングを勉強して簡単なサイトをつくってみたりしていた)こともあって、

photoructionを最大限使っていただけるようにサポートするよりも、使いやすいサービスを作ることでphotoructionユーザーの方々に貢献したいと思うようになりました。

2021年の初めにその思いを当時の上司に伝えてみたところ、「いいんじゃない?市橋くんに向いているかもね。やってみなよ!」とすんなり後押ししてもらえました。(大感謝です!)

その後、2021年3月からCSと兼務する形でPMグループに異動しました。

強み1 : 機能やユーザーの使い方を一番把握している


使いこなしてもらえるようにサポートするため、また、使い方に関するお問い合わせに対して適切に答えるためには、サポートする側が一番使い方を熟知している必要があります。

使い方を熟知するためには、文字通りすべての画面・すべてのボタンを確認しました。

この画面ではどんな挙動をするのか、これは何のための機能なのか、ユーザーの課題を解決するためにはどのように操作するのがいいのかを徹底的に確認します。

嬉しいこと(?)に、photoructionには多種多様な機能があるため、すべての機能を把握するためには日々触り倒して体に染み込ませる必要があります。(稀にお客様からのお問合せで存在を知る機能もあったり、、、)

PMとして新機能を企画する際には、既存の機能との親和性や機能追加することによる影響などを正しく把握する必要があります。

最前線でユーザーと向き合ってきたおかげで、PMに転向してからは既存仕様の理解にあてる時間はほぼなし。開発メンバーから仕様や既存の使い方を確認された際にも即時に返答することができています。

強み2 : 定量調査の経験を企画に活かすことができる


CSとしてユーザーの利用状況を正しく把握するためには、定例会でのヒアリング内容(定性データ)に加えて、アクティブ率などの定量的なデータも活用する必要があります。

私が入社した当時、アクティブ率やデータ量の推移は逐一エンジニアに確認しないと取得できない状況だったため、自分たちで取得できるような仕組みをつくることにしました。

Google Analyticsを用いたアクティブ率の算出や、SQLを書いてデータベースに蓄積されたデータの取得をしながら、利用状況確認用のダッシュボードを作成しました。

(私がCSから異動したあとの今でも、KPIとして活用されています)

私がPMになった時点では、企画段階で定量データを確認する習慣がありませんでした。

仕様検討時に、既存ユーザーの活用状況や蓄積データ量を確認しておくことで、企画精度の向上や開発メンバーに説明する際にも納得感のある説明を行うことができます。

私がPMグループになってからは、社内で非エンジニア向けのSQL勉強会を主催し、PMグループのメンバー全員がデータを見るクセを付けられるように動いています。

また、photoructionの開発組織では、今後ユーザーの行動ログ解析ができるような体制をつくっていく動きをしています。

今後はより精度の高い定量データや、ユーザーインタビューによる定性的なデータなどを活用して、より利用していただいている方々のためになるようなサービス開発をしていきたいと思っています。

苦労 : 開発に関する知識が不足している


photoructionのPMグループは、開発する機能の企画部分(プロダクトマネジメント領域)と、企画した機能をリリースまで持っていく部分(プロジェクトマネジメント領域)を担っています。

企画の部分については、建設業に関するドメイン知識(私は道路計画が専門だったので、建築の施工についての知識は十分ではありませんが)と、CSで培ったユーザーとプロダクト理解の部分でカバーしています。

ただ、プロダクトマネージャー界隈で有名なThe Product Management Triangle でも記されているとおり、PMに求められるスキル・知識はユーザー・ビジネス・開発というとても広い領域で求められます。

特に、プロダクト開発やUI/UXデザイン領域については0からのスタート、かつ、プロジェクトマネジメント部分も任されていることもあってとても苦労しています。

PMという立場上、実装する上での実装難易度の想定であったり、エンジニアからの技術的な提案を受ける際にも、素早く適切な意思決定をしないといけません。

今の開発チームのメンバーは、私が開発領域の知識が少ないことを考慮して、分かりやすい表現を使っていただいていますが(大感謝)、素早く質の高い意思決定をするためには、開発に関する知識がどうしても必要になってきます。

まとめ


前述のとおり、世間一般的に言われるプロダクトマネージャーとして必要なスキル領域はとても広く、実際にやってみるとものすごく難しく感じます。

ただ、最初からすべてのスキルを持っている人はそうそういないのと、色々なバックグラウンドを持ったPMがチームにいたほうが、不足している部分をお互いに補えるので強いチームになれると思います。

現在のPMグループは私を含めて3名在籍しています。

建設業界出身という共通点はありますが、持っているドメイン知識領域はそれぞれバラバラですし、スキル面でも得意不得意な領域はそれぞれ異なっています。

そのおかげで、不足している部分をお互いで補うことによって、チームとしてプロダクト開発に臨めています。

私にPMとして期待されていることは、CS出身者である強みを生かして、photoructionを利用していただいている方の気持ちを一番理解しているPMになることだと思っています。

今、開発畑以外のところで活躍している方々で、PMへの転向を考えている方は、「いいプロダクトをつくりたい」という気持ちと「自分がプロダクトをつくる上で活かせることはなにか」を考え続けることが一番大事だと思います。

最後まで読んでいただきありがとうございました!

Photoruction Advent Calendar 2021の投稿はまだまだ続きます。

他の記事も是非読んでみてください!

 

株式会社フォトラクションでは一緒に働く仲間を募集しています

corporate.photoruction.com

www.wantedly.com

LaravelプロジェクトにViteを用いてVue + Composition API + TypeScript環境を構築

こんにちは!株式会社フォトラクションでWebエンジニアをしています南風原はえばる)です。 Photoruction Advent Calendar 2021の9日目の記事です。

導入

現在、担当している案件のフロントエンドがほぼリプレイス並みの開発というタイミングもあり、技術スタックを新しく見直しました。

開発環境はViteを用いてVue.js + Vue Composition API + TypeScriptで機能開発を行っています。

今回は環境構築までの流れを書いていこうと思います。

 

その前に、現状のPhotorucutionのフロントエンド事情を軽く説明します。

プロダクトの約7割はBackbone.js、jQueryで実装されており、画面の表示はHandlebars.jsというテンプレートエンジンとLaravelのbladeファイルを用いて実装されています。

3年くらい前から新機能の開発はVue.jsで開発していく流れにはなっていますが、まだまだレガシーコード満載な状況です笑

今後さらにフロントエンドの開発環境が良いものとなるように一緒に改善に取り組んでいけるエンジニアを絶賛募集中です!

Viteとは

ViteはVue.jsの開発者であるEvan You氏が開発しているノーバンドルで高速に動作するビルドツールになります。

「ヴィート」と読むそうで、フランス語で「高速」の意味らしいです。(このツールを知った当初は、バイトって読んでました笑)

「高速」というだけあって、プロジェクトの作成も一瞬。ビルド時間もあっというまで開発体験がめちゃくちゃいいです。

Vue.js以外にも、ReactやPreactのビルドもサポートしているそうです。

vitejs.dev

環境構築編

[前提] 既存プロジェクトの大体のディレクトリ構成になります。

root/
 ├ app/
 ├ bootstrap/
 ├ config/
 ├ database/
 ├ public/
 │ └ js/
 │   └ dst/
 ├ resources/
 │ └ assets/
 │   └ js/
 │    └ app/
 │ └ lang/
 │ └ views/
 ├ package.json

1. Viteを使って新しくプロジェクトを作成

既存プロジェクトで使用しているパッケージとは分離するために、新しいディレクトリを作成しViteをインストールします。(メッセージの指示に従って環境のセットアップをしていく)

$ mkdir resources/assets/js/app/[newProject]
$ cd resources/assets/js/app/[newProject]
$ npm init vite@latest

2. Viteで作成した新プロジェクトに移動しビルド実行

$ cd [newProject]/
$ npm install
$ npm run dev

3. Viteプロジェクトのビルド時に生成されたファイルの出力先を変更

vite.config.js 内にビルド時のファイル出力先を既存プロジェクトのファイルパスになるようにします。

build: {
  outDir: '../../../../../public/js/dst/[newProject]'
},

4. scssファイルのインポート設定

vite.config.js 内にコンポーネント共通で参照するscssファイルのパスを追加します。

css: {
    preprocessorOptions: {
      scss: {
        additionalData:
          `@import "./src/assets/scss/variables.scss";
          @import "./src/assets/scss/common.scss";`,
      }
    }
  }

5. 既存プロジェクト(Laravel)にViteプロジェクトを読み込むヘルパー関数を作成

<?php

use GuzzleHttp\\Client;
use Illuminate\\Support\\HtmlString;

function vite_assets($path, $fileName): HtmlString
{
    $devServerIsRunning = false;
    if (config('app.env') === 'local') {
        try {
            $client = new Client();
            $res = $client->get("<https://localhost:3000/{$fileName}>");
            $devServerIsRunning = true;
        } catch ( \\Exception $e ) {
        }
    }
    // ローカルサーバに接続できた場合
    if ($devServerIsRunning) {
        return new HtmlString(<<<HTML
            <script type="module" src="<https://localhost:3000/@vite/client>"></script>
            <script type="module" src="<https://localhost:3000/{$fileName}>"></script>
        HTML);
    }
    // その他の環境ではコンパイルしたjsを返す
    $manifest = json_decode(file_get_contents(public_path("{$path}/manifest.json")), true);
    return new HtmlString(<<<HTML
        <script type="module" src="/{$path}/{$manifest[$fileName]['file']}"></script>
        <link rel="stylesheet" href="/{$path}/{$manifest[$fileName]['css'][0]}">
    HTML);
}

※ローカルサーバー(https://localhost:3000/)で開発する際はlocalhostへのアクセス許可が必要になります。

LaravelのbladeファイルにVueコンポーネントをマウントする方法

既存機能の一部分に新しく作成したVueコンポーネントを表示したいパターンが有るかと思います。

その場合の方法を紹介します。

import FeatureContent from '@/pages/FeatureContent.vue'

// 任意の要素(DOM)の変化を監視する
const observer = new MutationObserver(records => {
  records.forEach(mutation => {
    const target = (mutation.target as any).getAttribute('id')

    switch (target) {
      case 'feature_content': {
        const app = setFeatureContentApp()
        vue = app
        break
      }
    }
  })
})

const featureApp = document.getElementById('feature_app')

if (featureApp) {
  observer.observe(featureApp, {
    attributes: true,
    subtree: true,
    attributeFilter: ['class'],
  })
}

// Vueコンポーネントを任意のDOMにマウントする
const setFeatureContentApp = () => {
  const featureContentElm = document.getElementById('feature_content')
  if (!featureContentElm) return
    return new Vue({
      render: (h) => h(FeatureContent),
    }).$mount('#feature_content')

bladeファイル

<div id="feature_app">
  <div id="feature_menu">
	<!-- 既存View -->
  </div>
  <div id="feature_content" /> ← 新Vueコンポーネントがマウントされる
</div>

まとめ

Backbone.jsで作成された既存機能をVue.jsにリプレイスしていく場合、全てを一から作り直すというのは時間と開発コストがかかります。

上記のような方法で、既存機能への影響を最小限に抑えながら少しずつリプレイスをしていくことが可能だということを今回担当している案件を通して学べました。

これから先、UI/UX含めフロントエンドをどんどんアップデートしていき、ユーザへより一層価値の高いサービスを提供できるようなプロダクトを作っていきたいものです。

ぜひ、一緒にフロントエンド開発を盛り上げていただける方をお待ちしております!

 

株式会社フォトラクションでは一緒に働く仲間を募集していますhttps://corporate.photoruction.com/careers/

corporate.photoruction.com

www.wantedly.com

Photoructionリリースするまでのテストについて(今ある課題と今後の取り組み)

こんにちは!株式会社フォトラクションでQAグループのリーダーをしている塩谷です。 Photoruction Advent Calendar 2021の8日目の記事です。

 

本日はPhotoructionを開発していく中でどのように品質を担保しているのか広めたいと思い、リリースするまでのテスト業務について記事にしてみました。

目次


1.はじめに
2.リリースまでのプロセス
3.開発環境でのテスト
4.リリース環境でのテスト
5.課題と今後

はじめに


私の経歴とフォトラクションのQAグループについてご説明いたします。

 

私は、大学卒業後に某SIer企業に入社いたしました。そこでは仕様策定や評価業務など様々なプロジェクトに従事し、プロダクト開発における上流工程〜下流工程の経験とスキルを積みました。

フォトラクションに入社する直前にはプロジェクト管理者として評価プロジェクトの管理を行っており、その経験が今に繋がっていると感じています。

 

2020年5月に縁があってフォトラクションに入社することになり、その際にCEOの中島からはQAグループを作って欲しいというミッションが与えられました。

当時のフォトラクションにはQAグループが存在しておらず、開発における評価業務はエンジニアがテスターにテストを依頼するという形をとっていました。

ゼロからQAグループを作ることになったので手探り状態でしたが、身の回りの細かいことからコツコツと進めていくことで今のQAグループが出来上がってきたと思います。

リリースまでのプロセス


Photoructionが開発されてからリリースされるまでのプロセスについてご説明いたします。

現在おおよそ1ヶ月に1回新規機能のリリースを行なっており、その際は下図のような開発フローを採用しております。

リリースまでには大きく分けると開発フェーズとリリースフェーズの2つのフェーズが存在しています。

  1. 開発フェーズ
    各開発のフィーチャーブランチで実装を行い、開発環境を作成してテストするフェーズになります。実装〜テスト・各種レビューまで行い開発フェーズが終了します。
  2. リリースフェーズ
    リリースブランチを作成して各フィーチャーをマージしたリリース環境でテストするフェーズになります。 バグが発生したらその都度改修を行い、バグの改修が完了したらリリースフェーズが終了します。

f:id:photoruction_tech_blog:20211202151623p:plain



開発環境でのテスト


開発環境のテストでは、単体テスト結合テストに位置付けられるテストを実施します。

各開発案件にアサインされているQAエンジニアがテストケースを準備し、テスターにテスト実施を依頼します。

テストケースの内容は企画書・仕様書から機能的な確認項目を作成し、QAグループ内のレビュー、PM・エンジニアとのレビューを経て完成します。

それぞれの開発に対して環境を準備してテストすることで開発毎に品質を確保した上でリリース環境にマージしリリースフェーズに臨みます。

各開発についてリリースターゲットはあらかじめ計画していますが、開発環境でのテストをパスできない場合は、リリースターゲットの変更など対策を行います。

リリース環境でのテスト


リリース環境のテストでは、各開発のテストケース再走行とリリース前テストを実施します。

テストケースを再走行する目的は、マージ後の予期せぬデグレの検出となります。

Photoructionは機能的にも実装的にも複雑化しており、各開発をマージした後に予期せぬバグが発生することがあります。

そのため、マージ後の環境でテストケースを再走行することでバグ流出を防ぐように取り組んでいます。

テストケースの実施とバグの改修が完了したら、リリース前の最終テストを実施します。

リリース前テストは開発内容によらず固定のテストケースを実施しており、

内容は全機能の基本的な動作の確認になります。

以前はリリース前テストは実施していませんでしたが、リリース物に対して総チェックを行うべきとの考えからリリース前テストを実施することにしました。

導入した当初は開発に関わるものそうでないものなど様々なバグを検出していましたが、徐々にバグ検出数が減少し、品質が向上してきていると考えています。

全てのテストをパスしたらリリースされます。

課題と今後


フォトラクションのQAグループでは、様々な課題を抱えておりますが、

当然ながら最も重要な課題は市場へのバグ流出を防ぐことだと考えています。

「リリース環境でのテスト」の項でもご説明した通り、リリース環境では各開発の2サイクル目のテストを実施しております。

マージによるデグレリスクを低減させることができれば、同じテストを2サイクル実施するのではなく、別の観点でのテストを実施することで今まで防げなかったバグの流出を防げる可能性が出てきます。

デグレの低減についてはQAグループだけの取り組みでは、改善させることが難しいので開発部門と連携をしながら改善に取り組んでいます。

また、リリース前テストなど定型的なテストについては、自動テストの導入に取り組んでおり、自動テストでまかなえるテスト工数の分だけ別のテストを導入することができます。

自動テストは誰でも実行できるようにすることで、例えばエンジニアが任意のタイミングで実行し早期にデグレなどのバグを検出できる効果も期待できます。

他にも発生したバグ分析やバグの発生数を減らす施策の検討などQAグループとして課題は多く残っている状況ですが、QAグループがリリースされる前に最後までPhotoructionを触っているので”最後の砦”とという自覚を持ち、地道にコツコツと品質を上げていけるようにこれからも努力を続けていきたいと思います。

 

 

今回の記事を通してフォトラクションも品質を向上できるように考えているということが少しでも伝われば幸いです。

ありがとうございました。

 

株式会社フォトラクションでは一緒に働く仲間を募集しています

 

 

Vueのシングルファイルコンポーネント(SFC)を生Javascriptアプリで使おう!

株式会社フォトラクション WEBチーム所属 ジョンです!
Photoruction Advent Calendar 2021の7日目の記事です。

Vueのシングル・ファイル・コンポーネントをSPAではないプロジェクトに使える方法を紹介したいと思います。

目次



フォトラクションでは、アプリケーションの改善を常に行っています。それの一つの計画としては今のアプリケーション内に古く書かれているBackbone.jsとjQueryを最もモダンなフレームワーク、Vue.jsに書き直すことです。

だが一つ問題があり、レガシーコードを書き直しながら新しい機能を増やすことも大事で私たちのリソースをコードの書き直しだけに無駄に使うのがふさわしくない。そのため、Backbone.jsやjQueryで書かれているコードにも新しい機能を追加することもよくあるのです。ソースコードをすべてVue.jsに書き直すついでにBackbone.jsやjQueryをこれ以上増やしたくないので、新しい機能もVueで開発したかったです。

なお、Vueにはいろいろ書き方があります。その一つはSFCを使わずに直接Vueのインスタンスを作ることです。もちろんこのような書き方にしても問題ないですが、VueのSFCのメリットを得られなくなる上に管理もしにくくなります。

<!DOCTYPE html>
<html>
    <head>
        <title>俺のものすごいアプリ</title>
    </head>
    <body>
        <div>
            <!-- 既存コード -->
        </div>
        <div id="my-vue-component">
            <other-component />
        </div>

        
        <script
            src="https://code.jquery.com/jquery-3.6.0.min.js"
            integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
            crossorigin="anonymous"
        ></script>
        <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
        <script>
            $(document).ready(() => {
                ...既存コード
            });

            Vue.component('other-component', {
                data() { ... },
                template: '...'
            });
    
            new Vue({
                el: '#my-vue-component',
                template: '...',
                data() { ... },
                methods; { ... }
            });
        </script>
    </body>
</html>


では、早速始めましょう!

前提条件

Node.js - npmからVueやwebpackなどをダウンロードするため、Vueのシングル・ファイル・コンポーネントはそのままJavaScriptに使うことができないため、コンパイルする必要があります。

シングル・ファイル・コンポーネント(Single-File Component)

<template>
    <button>
        <other-component />
        <slot />
    </button>
</templaet>

<script>
import OtherComponent from './OtherComponent.vue';

export default {
    component: {
        OtherComponent
    },
    data() {
        return { ... };
    },
    methods: { ... }
};
</script>

<style scoped>
button {
    padding: 1rem 2rem;
}
</style>

Vueのシングル・ファイル・コンポーネントは基本的に.vueという拡張子が付いています。この.vueファイルにはHTML、JavaScriptCSSをまとめてバンドルすることができます。Vueでシングル・ページ・アプリケーション(SPA)を作ったことがある人には見慣れたコードになると思います。このファイルはSPAを作るときの.vueファイルと全く同じのため、他のコンポーネントやライブラリーをインポートすることはできますし、JavaScriptの代わりにTypeScriptを使うこともできますし、SASSなどを使うこともできます。

ローダーのスクリプト

先ほど作ったSFCを使えるために、ローダースクリプトを作ります。ローダースクリプトはVueコンポネントをアプリケーションにマウントさせるためのスクリプトになります。これがないとSFCを使用できません。

import Vue from "vue"; 
import MyComponent from "../components/MyComponent.vue";

const el = document.querySelector('#some-element'); 
new Vue(MyComponent).$mount(el);

VueでSPAを開発したことがある方は.vueファイルのようにこれも見慣れたコードになっていると思います。Vueのシングル・ページ・アプリケーションのindex.jsに書かれているものと同じです。ここで何をやっているのかというと、まずVueとプロジェクトに使いたいコンポーネントをインポートします。そして、new Vue(MyComponent)で新しいVueのインスタンスを作り、コンポーネントをパラメータとして渡します。それから、.$mount(el)でアプリケーション内の好きな場所にマウントします。

コンパイル

コンポーネントとローダースクリプトを完成したら、コンパイルする必要があります。コンパイルするためにはNode.jsが必要です。Node.jsはまだインストールしていない方には先にインストールしてください。Node.jsをインストールした後次へ進んでください。

Nodeで既に開発している場合

もしNodeですでに開発をしている場合はnpmから必要なパッケージのみインストールしてください。自分のプロジェクトにすでにインストールされているパッケージはインストールしなくていいです。プロジェクトにインストール済みのパッケージはpackage.jsonに確認できます。


まずは、vuevue-loadervue-template-compilerをインストールします。

npm install -D vue vue-loader vue-template-compiler


次はwebpackをインストールします。

npm install -D webpack webpack-cli


最後は.vueの中にあるCSSなどのためのローダーをインストールします。

npm install -D @babel/core babel-loader css-loader vue-style-loader

今回はシンプルにしたいため、SASSなどを使わないですが、もしSASSが必要であればsass-loaderなどをインストールする必要があります。


次は、webpack.config.jsを修正します。


webpackが使われていないプロジェクトにはこのファイルが存在していない可能性あります。であれば、プロジェクトのrootwebpack.config.jsのファイルを作成してください。

const { dirname } = require("path");
const VueLoaderPlugin = require("vue-loader/lib/plugin");

module.exports = {
  entry: {
    "favorite-cat": "./vue/loaders/favoriteCatLoader.js",
  },
  output: {
    filename: "bundle.js",
    path: __dirname,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: "vue-loader",
      },
      {
        test: /\.js$/,
        loader: "babel-loader",
      },
      {
        test: /\.css$/,
        use: ["vue-style-loader", "css-loader"],
      },
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
  ],
};

webpack.config.js確認

  1. webpack.config.jsはすでにあるプロジェクトには上記の内容が自分のwebpackコンフィグに存在しているかどうか確認してください。
  2. module.exportsmodule.ruleの順番が大事なので、webpack.config.jsを修正するときに注意をしてください。


新しいコンポーネントやローダースクリプトを追加するときに、module.exportsentryに追加しなければなりません。

module.exports = {
  entry: {
    "comp1": "./loaders/ComponentLoader1.js", 
    "comp2": "./loaders/ComponentLoader2.js",
    "comp3": "./loaders/ComponentLoader3.js",
  },
 ...
}

プロジェクトのrootpackage.jsonを開いて、下記を追加してください。

"scripts": {
    "build": "webpack --config webpack.config.js --mode development"
},


プロジェクトに初めてNodeを使った場合にはwebpack.config.jsみたいにpackage.jsonも存在していない可能性があります。その場合は、下記を実行し、プロジェクト情報を入力してください。

npm init

そのあとは上記のpackage.jsonファイルの編集を行ってください。


最後にはビルドをします。

npm run build


上記のコマンドを実行したら、プロジェクトのrootbundle.jsが生成されます。そのbundle.jsをHTMLの中にインクルードします。

<html>
    <body>
        ...
        <script src="bundle.js" defer></script>
    </body>
</html>


そのあと、HTMLにコンポーネントのマウント先を作ります。
ロードスクリプト#some-elementコンポーネントをマウントしようとしているため、<div id="some-element"></div>を追加すれば、Vueコンポーネントはこのdivの中にマウントされます。

まとめ

自分のプロジェクトはVueのシングル・ページ・アプリケーションではなくてもVueのシングル・ファイル・コンポーネントを使えます。上記でいろいろやりましたが結局3つのステップで済むことができます。

1. Vueコンポーネントを作成
2. ローダースクリプトを作成
3. ビルド

今までのスパゲッティコードを何とかしたいけど、今のプロジェクトをSPAに書き換えることができない人は是非やってみてください!


株式会社フォトラクションでは一緒に働く仲間を募集しています
corporate.photoruction.com
www.wantedly.com

AWS Lambdaを効率良く開発する!

株式会社フォトラクション WEBチーム所属 下川原です! Photoruction Advent Calendar 2021の6日目の記事です。

この記事ではAWS Lambda for Node.jsを効率良く開発するためのTipsを紹介します!

まずはじめに必要なもの


  • windowsの方はwslなどインストールしておくと吉(コマンドプロンプトプロフェッショナルは、読み替えてください)
  • IDEは自分が馴染むやつ
  • AWSのアカウント

目次


 

初期構築


インストールしておくべきもの

https://aws.amazon.com/jp/cli/

  • AWS SAM CLI (Lambdaをローカルで実行するのに必要)

https://aws.amazon.com/jp/serverless/sam/

  • aws-vault (MFAを使用しているAWSアカウントは、インストールしておくと幸せになる)

https://github.com/99designs/aws-vault#installing

  • makeコマンド(それぞれの環境に合ったインストール)下記はapt例
$ sudo apt install make
$ sudo apt install make-guile

ディレクトリ構成


lambdanodejs 
├── Makefile ※2
├── [Readme.md](<http://readme.md/>) お好きにどうぞ
├── debug-env.json ※3 
├── events
│   └── request-sample.json ※3
├── libs ※4
│   ├── Makefile
│   └── nodejs
│       ├── package-lock.json
│       └── package.json
├── samconfig.toml ※5
├── src ※4
│   └── lambdanodejsMaster
│       ├── lambdanodejsMaster.js
│       └── package.json
└── template.yml ※1

template.yml ※1


AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Lambda Nodejs

Resources:
   lambdanodejsMaster:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: lambdanodejsMaster
      Role: ${lambdaを実行するロールのARN}
      Handler: lambdanodejsMaster.lambdanodejsHandler
      CodeUri: ./src/lambdanodejsMaster
      Runtime: nodejs14.x
      Timeout: 300
      MemorySize: 128
      Layers:
        - !Ref LibsLayer
      Environment:
        Variables:
          ENV_SAMPLE: SAMPLEDONE
  LibsLayer:
    Type: AWS::Serverless::LayerVersion
    Metadata:
      BuildMethod: makefile
    Properties:
      LayerName: libs
      Description: Libraries
      ContentUri: ./libs
      CompatibleRuntimes:
        - nodejs14.x
      RetentionPolicy: Retain

参考

AWS Lambda テンプレート Cloud Formation

LambdaのMemorySizeによってCPUのスペックが決まる話

AWS Lambda のリソースモデルでは、お客様が関数に必要なメモリ量を指定すると、それに比例した CPU パワーとその他のリソースが割り当てられます。メモリサイズが増えると、関数で利用可能な CPU にも同等の増加が発生します。

makefile ※2


.PHONY: build clean test

LAYER_ARTIFACTS_DIR=.aws-sam/build/LibsLayer
LAYER_NODE_MODULES=$(LAYER_ARTIFACTS_DIR)/nodejs/node_modules

.aws-sam/build.toml: template.yml samconfig.toml src/*.js libs/nodejs/package-lock.json
   sam build

build: .aws-sam/build.toml

deploy:
   make clean
   make build
   sam deploy

clean:
   rm -rf .aws-sam

test:
   cd libs &&ARTIFACTS_DIR=../$(LAYER_ARTIFACTS_DIR)make build-LibsLayer-test
   cd src &&PATH=../$(LAYER_NODE_MODULES)/.bin:${PATH} NODE_PATH=../$(LAYER_NODE_MODULES)npm test

jsonファイル ※3


debug-env.json

ローカル実行時の環境変数ファイル

デプロイするときは必ずtemplate.yamlに記載する

{
  "lambdanodejsMaster": {
    "ENV_SAMPLE": "SAMPLEDONE"
}

request-sample.json

lambda関数に渡すリクエス

nodejs内関数Handlerの第一引数で受け取れる(変数名: event)

{
  "key": "sample value"
}

src ※4


nodejs本体のディレクトリ 詳しいことはnodejsを参考に

Node.js の AWS Lambda 関数ハンドラー

lambdanodejsMaster.js 最低限必要なもの

exports.lambdanodejsHandler = async (event, context, callback) => {
	console.log(event);
	callback(null,event);
}

samconfig.toml ※5


AWS SAM CLI の設定ファイル

例)

version = 1.0
[default]
[default.deploy]
[default.deploy.parameters]
stack_name = "stack"
s3_bucket = "${配置するS3のARN}"
s3_prefix = "${配置するS3のprefix}"
region = "ap-northeast-1"
confirm_changeset = true
capabilities = "CAPABILITY_IAM"

ローカル実行!


# nodejsをビルドする
$ sam build

# ローカル実行
# -n envファイルのパス
# -e 関数へ渡す引数のパス
$ sam local invoke lambdanodejsMaster-n ./debug-env.json -e ./events/request-sample.json

# AWS Lambdaへデプロイをする
$ sam deploy

これで、AWS Lambda関数をローカルで快適にガシガシ開発できます!

よいデベロッパーライフを!

 

株式会社フォトラクションでは一緒に働く仲間を募集しています


 

フォトラクションのCREって何やってるの?

こんにちは!株式会社フォトラクションでCREグループのリーダーをしています脇田慎平です! Photoruction Advent Calendar 2021の5日目の記事です。

フォトラクションのCREチームがどんなことをやっているか、紹介します!

CREとは?


Customer Reliability Engineering(顧客信頼性エンジニアリング)の略で、2016年にGoogleが提唱した専門職です。

日本でCREを組織として持っている会社だと、メルカリさんやはてなさん、アンドパッドさんなどが有名でしょうか。

CREはまだ歴史が浅く、会社によってもCREの定義・役割は様々なようです。

フォトラクションは、2021年1月にCREチームを発足しました。

開発チームが抱えていた課題


CREチーム発足以前のフォトラクションにおける開発組織の喫緊の課題として、「緊急性の高いバグ対応により、新規開発のスケジュールが遅れる」というものがありました。

そもそも不具合が発生しないようにしなければならないのは大前提ですが、システム開発をしている以上どうしてもバグは発生してしまいます。フォトラクションは建設現場で使用される施工管理アプリであり、バグの内容によってはお客様の業務が完全に止まってしまうことになります。

そうした緊急性の高いバグが発生した場合は、新規開発を止めて全力でバグ対応を行います。無事にバグ改修をリリースした後、新規開発に戻ります。

しかしこれでは、"いつ起こるか分からない"バグ改修に新規開発のリソースが使われることになり、スケジュール通りの開発は困難になります。

また、これまではどちらかというと「ガンガン作っていこう!」という開発スタイルだったので、解消されるバグ数よりも新たに発生するバグ数の方が多くなってきました。「本当にクリティカルで今すぐ直さないとお客さまの業務に大きな支障が出る」というレベルのバグ以外は、少しずつ後回しになりがちになっていました。

フォトラクションのCRE


そんな課題を解決すべく、フォトラクションでは2021年1月にCREチームを立ち上げました!

現在フォトラクションのCREが担う役割は以下です。

  1. お客さまからの問い合わせおよびバグ改修において責任を持つ
  2. 資産となる既存アプリケーションの価値を守る
  3. 他グループがアプリケーション開発、価値創造に集中できる環境を作る

当初の課題であった「新規開発とバグ改修とのリソースの分離」の文脈だけでなく、CREの本来のミッションである「顧客信頼性を高めること」、つまり「お客さまの不安を取り除くこと」にもフォーカスした役割設定になっています。

具体的な業務内容


ではフォトラクションのCREが具体的に何をしているのか、簡単に紹介します。

バグ改修

前述の通りです。これまで新規開発チームがやっていたバグ改修はCREで行います。おかげで、新規開発チームは集中して開発を行うことができるようになりました。

カスタマーサポートチームが受けたお客さまからの技術的な問い合わせ対応

こちらは多岐に渡ります。問い合わせへの対応はカスタマーサポートが担当するのですが、回答する上で技術的な知識が必要とされる問い合わせに対し、CREチームが窓口となって調査を行います。「今まさに現場で困っている!」というご相談もあり、スピーディーな対応が求められます。

あくまで調査の窓口であるので、CRE内で全てを解決するというわけではありません。QAチーム、PMチーム、新規開発チームと連携をとり、必要な協力を仰ぎながら解決を目指します。ここは窓口であり一次切り分けを行うCREの腕の見せ所でもあります!

カスタマーサポートが要望する社内ツール開発

フォトラクションでは、カスタマーサポートからお客さまへ提出するレポートの出力などで、一部社内向けに開発も行っています。こうした社内向け開発もCREで担当しています。

やりがい

個人的に一番のやりがいは、「お客さまの生に近い声が聞ける」ことだと思います。お客さまとの直接の窓口であるカスタマーサポートチームと密にやりとりをする中で、お客さまからの声(良いもの・良くないもの両方)に触れることが多くなります。

フォトラクションもそれなりの規模感になってきて(社員60名弱)、なかなか開発チームにお客さまからの声が届きにくくなってきているのが正直なところです。

「目の前で困っている人の課題を解決し、その感謝の声を聞くことができる」というのは、やはりやりがいがあります。

CREの使命の一つは「バグを解消してお客さまの不安を取り除く」ことですが、そもそもバグが発生しない方がイイに決まっています。開発組織全体の課題として、「バグの発生を抑える」ことに現在全力で取り組んでいるところです!!!

どんな人が活躍できそう?

フォトラクションのCREでは、どんな人が活躍できるだろうか?ということをしばらく考えてみた結果、

  • WEB開発経験がある
  • 柔軟なコミュニケーションが取れる

という結論に辿り着きました。「『技術力とコミュニケーション能力が大切』なんて誰でも知ってるわ!!!百万回聞いたわ!!!」って感じですが笑、やっぱりここに集約されると思います。

WEB開発の経験がある

「カスタマーサポートが答えられない技術的なサポートをする」という役割である以上、そのベースとなるWEB開発の経験は非常に大切であります。

前述したように、お客さまの業務が止まってしまうようなバグが発生している時には、スピーディーな対応が求められます。時には、「まず業務が再開できるような一次対応を短時間で行ったのち、同じバグが二度と発生しないための恒久対応を行う」といった柔軟な判断も求められます。

フォトラクションのCREも、経験豊富なメンバーの技術力によって支えられています!

柔軟なコミュニケーションが取れる

お客さまとの直接の窓口であるカスタマーサポートチームだけでなく、バグの再現やリリーススケジュール調整のためにQAチームとも連携をとりますし、仕様のすり合わせのためにはPMチームと、そして当然他のエンジニアとも連携して動く必要があるのでエンジニアチームともコミュニケーションが発生します。

開発関係者だけでなく営業サイドとのやりとりも多いです。

特に非エンジニアであるカスタマーサポートチームと会話する際には、技術的な用語をできるだけ使わない・お客さまにも伝わる言葉で伝えるといった意識が必要です。

相手によって柔軟に対応できるコミュニケーションスキルは、非常に大切になりますね。

これからやっていきたいこと

CREという概念自体5年ほど前に生まれたばかりで、世の中にもモデルケースと呼ばれる事例はとても少ないです。また、ビジネスモデルやサービス規模によっても、CREが求められる役割は大きく異なるはずです。

現在フォトラクションのCREは、バグ改修やカスタマーサポートの支援(技術的課題の解決・社内ツール開発)などを主な役割としています。世の中に正解がない中で、「CREチームはフォトラクションの中でどういう役割を担うべきか」という議論は、まだまだ社内でも必要だと思います。というより、サービス・会社の成長とともにCREの役割も常にアップデートし続けていかなければなりません。

まだ歴史の浅いCREという領域において、フォトラクションの事例が代表的な一例となっていけるよう、今後も精進していきます!

まとめ


フォトラクションアドベントカレンダー、明日からも現場のリアルな声が詰まった魅力的な記事が続きます!ぜひ見てもらえると嬉しいです。ありがとうございました!

 


株式会社フォトラクションでは一緒に働く仲間を募集しています