Vue Devtools で快適なデバッグ

こんにちは、 SCOUTER エンジニアの匠平@show60です。

SCOUTER のフロントエンドの開発は Nuxt.js を使用しており、デバッグの際に Vue Devtools というツールを使っています。

今回はこの Vue Devtools で、開発に普段使いしてもらいたい機能をいくつかご紹介したいと思います。

Vue Devtools の導入

最も人気がありシンプルなのは、Chrome 向け および Firefox 向け の優れた Vue.js devtools を使用することです。

VS Code によるデバッグ — Vue.js

Vue Devtools の導入には、拡張機能とデスクトップアプリケーションの2つの方法があります。

Chrome と Firefox は拡張機能が提供されており、普段の Devtools と同じように開けるのでこちらが便利でしょう。

他のブラウザをお使いの方は、デスクトップアプリで使用することになります。

ここでは Chrome 拡張機能を用いて、以下のとおりシンプルな Nuxt.js アプリケーションを例にしたいと思います。

f:id:show-hei:20190514212914p:plain

Vue Devtools の基本機能

Devtools とは、ブラウザで使用できるデバッグツールで、主にフロントエンド開発に使用します。

3月末に Vue Devtools が ver 5 にアップデートされ、新しい機能が追加されました。

基本機能に大きな変更はありませんが、新たに追加された機能、強化された機能を織り交ぜて紹介します。

  • イベントの動作をレコーディング
  • パフォーマンスタブでレンダリング時間を計測
  • Vuex 内のデータを編集
  • 試してほしい便利機能

イベントの動作をレコーディング

このタブでは、アプリ内で行われたイベントをレコーディングし、それらの動作によって正しくデータが渡されているかを確認することができます。

以下のサンプルの input は、 AppInput.vue というコンポーネントとそのラッパーである InputWrapper.vue で構成されています。

f:id:show-hei:20190514214644g:plain

input タグにテキストを入力すると、中央にそのタグ名や時刻などが表示され、右側は event info 、つまりイベントの詳細が書かれています。記録されるイベントは $emit が対象となるようです。

event info の項目

  • name
    • イベント修飾子の名称
  • type
    • イベントの種類 (Vue Devtools の Github を見る限り、表示されるテキストは $emit しかないよう)
  • source
    • イベントを含んでいるコンポーネント名
  • payload
    • 受け渡されたデータ

このサンプルでは単純な構成ですが、複数のコンポーネントを経由してデータを受け渡すことも多いでしょう。

目的のページやコンポーネントまでデータが渡らないというときに、どのコンポーネントまで渡ってきているのかが視覚的に分かりやすくなります。

1動作ごとに記録ができるので、ほしいデータが膨大な記録に埋もれてしまうといった心配もないですね。

パフォーマンスタブでレンダリング時間を計測

パフォーマンスタブ内では2つの方法でパフォーマンスを計測することができます。

Frames per second

Vuex やルーティングなどの動作のパフォーマンスを計測することができます。 レコーディングを Start し、ブラウザ操作を行った後に Stop するとその間のパフォーマンスを秒単位計測することができます。

f:id:show-hei:20190514225955p:plain

アルファベットが書かれた丸いアイコンが、その動作を示しています。

  • E: Events
  • R: Routes
  • M: Mutations

Vuex の Mutations の動作が記録されるため、動作のタイミングを確認したり、重複している動作を見つけるのにも役立ちそうです。

f:id:show-hei:20190514230409p:plain

計測したパフォーマンスは自動的に保存されるため、複数回の計測で比較することもできますが、表示が秒単位なので細かな分析には向いていないかもしれません。

Component render

こちらもレコーディングを Start してから Stop するまでの時間を計測することができますが、コンポーネント単位でのレンダリングを表しています。

f:id:show-hei:20190515034044p:plain

右側には Vue.js の Lifecycle hooks の関数と同名の項目が並んでおり、各項目ごとの処理時間がミリ秒単位で記されています。

手元のコードで動かしてみる限り、 mountRenderupdateRender あたりのレンダリング処理は他の処理と比べて時間がかかるようです。

ページやコンポーネントの処理に時間がかかるなどといった場合のデバッグに利用できそうです。

Vuex 内のデータを編集

以前のバージョンより、 Vuex の state, mutation, getters を確認することができていましたが、 Ver 5 のアップデートからは新たに Devtools 上で Vuex を編集できるようになりました。

f:id:show-hei:20190515044042g:plain

ブラウザ上に表示されるテキストであればブラウザの Devtools で編集してしまうと思います。

そうでない裏側で動いている Vuex のデータで、ちょっと値を変更して確認したいだけなんだよなーってときにはとても便利です。

数値であれば + - で簡単に増減できますし、配列の要素も同様に増やすことができます。

試してほしい便利機能

Vue Devtools の隅っこの見逃しそうな場所に inspect DOMOpen in editor があります。

f:id:show-hei:20190515111448p:plain

ブラウザの横幅を縮めると見えなくなっちゃうのですが、もっと自信を持って表に出てきてもいいくらいの便利機能です。

ブラウザの Devtools にジャンプ

inspect DOM は、今開いているコンポーネント (ここでは <logo>) を通常のブラウザの Devtools の Elements で開いてくれます。

f:id:show-hei:20190515111609p:plain

わざわざ同じ箇所を再度探す必要がないので二度手間が省けてちょっとだけ嬉しくなれます。

見ているコンポーネントをエディタで自動的に開く

Open in editor をクリックすると、今開いているコンポーネントファイルをデフォルトエディタとして登録しているエディタで開いて表示してくれます。

f:id:show-hei:20190516110834g:plain

デバッグで当たりをつけたらこの Open in editor をクリックするだけですぐに修正を書き始めることができます。

これもコンポーネントを探す手間がいらないのでめちゃめちゃ便利です!

さいごに

基本機能を直感で簡単に使えるようになっている分、他の機能に触れることが少ないかもしれません。 かゆいところに手が届く仕様になっていると思うので、ぜひお試しください!

私達 back check チームは、日本の採用文化を変えるために、共にプロダクト開発をしていただけるエンジニアの募集をしております。

興味をお持ちいただいた方はぜひご連絡ください。

www.wantedly.com

www.wantedly.com

NuxtMeetUp#8 を開催しました

こんにちはみなさん niisan-tokyoです。

弊社ではアプリケーションの開発にLaravel + Vue.js を採用しておりますが、バックエンドとフロントエンドの分離を促進するために、最近ではバックエンドをLaravel、フロントエンドをNuxt.js で実装することが多くなっています。
そんななかで、過去最大規模である180人定員のNuxtMeetupを、令和初営業日の5/7に開催しまして、その開催報告を書いていこうかと思います。
nuxt-meetup.connpass.com

また、今回はスポンサーに株式会社ガイアックス様をお迎えし、イベントスペースを提供していただきました!

会場

会場は永田町にあるNagatacho GRiDさんのイベントスペースを使用させていただきました。 grid.tokyo.jp 設営のために到着した直後はこんな感じでした。

f:id:niikura23:20190509101052j:plain
会場
いい感じですね。
その後、人数規模に合わせて椅子を増設した結果、開催時にはこんな感じになりました。
f:id:niikura23:20190509101259j:plain
開催時の様子
改めて見てもすごい人数です。
それだけNuxt界隈が盛り上がっていることなのでしょう!

懇親会

ミートアップですので、セッションと同じくらい大事なのが懇親会です。
今回もたくさんの方に懇親会に参加していただきました。
その様子がこちらです。

f:id:niikura23:20190509101118j:plain
フード
f:id:niikura23:20190509104754j:plain
懇親会の様子

セッション

ミートアップといえばやはり濃密なセッションです。 すべて紹介するのは冗長なので、いくつかピックアップしていこうかと思います。

スタートアップがNuxtを採用するメリット

slides.com

株式会社テックピットの前山さんによるスポンサーセッションですが、Nuxtを採用する場面がどこなのか、実用に即して発表しておられました。
スポンサーはガイアックスさんではなかったのか、って思ったのですが、「Gaiax STARTUP STUDIO」という、スタートアップを同時多発的に生み出す組織にて立ち上がったスタートアップであるとのことでした。

axios-moduleをやめてaxiosを使う

slides.com

ピクセルグリッド所属で、副業で弊社のプロダクトにジョインしているじまぐさんによる発表です。
「プロダクトの成長を阻害する仕組みを排除する」という至言が飛び出す、個人的にとても感銘を受けた発表でした。

新規に参画したプロジェクトでNuxtに移植しようとした話

speakerdeck.com

株式会社オクトの藤井さんによる発表です。
現行システムをNuxtに移行している最中という、実例に即した現在進行形の話であり、今後Nuxt移行を進めたい方々にとっては貴重なセッションだったのではと思います。
「ブログで経過報告しているよ!」とのことなので、今後の推移が気になるところです。

まとめ

今回、NuxtMeetUpには初参加かつ開催側での参加ということもあり、いろいろ右往左往した部分もありましたが、参加者の方々のおかげで無事に終えることができました。

最後に

現在、株式会社SCOUTERでは、エンジニア、デザイナーの募集をしております。

興味のある方は、是非下記からご応募お願い致します!

www.wantedly.com

www.wantedly.com

www.wantedly.com

LaravelにおけるMVCの基本

こんにちは!
株式会社SCOUTER開発部フロントエンドエンジニアの佐藤(@r_sato1201)です

弊社では、Laravel+Vue(nuxt)で開発をしています。 私は普段、フロントエンドの開発を担当していますが、サーバーサイドでの開発もできるようにしたいと思いLaravelの学習を始めました。

学習を進めていても、初めはどのような処理の流れなのか、MVCって何?といった感じで全くどのような動きをしているのかが掴めませんでした。

今回はLaravel初学者の方向けに、MVCにそって
シンプルなTODOアプリの「ユーザーのブラウザにサイト画面が表示されるまで」を例に、自分が理解した基本的なLaravelの処理の流れを説明したいと思います。

DBは下記のような想定です。

tasks

カラム名 内容
title タスク名
content タスクの内容

MVCとは

MVCとはアプリケーションを実装するためのデザインパターンです。 複雑なアプリケーションの処理を3つの役割に分割することで、実装の見通しもよくなるというメリットがあります。

それぞれの役割は、

Model データ処理全般。DBへのアクセスに関する処理を行う
View 画面表示を担当。ユーザーに表示する情報を出力する
Controller 全体の制御を担当。ユーザーからの入力をモデルに渡したり、モデルから渡されたデータをビューに渡し画面に表示する役割を担う

となっています。

ルーティングの設定

まずはルーティングです。 ルーティングとは、アクセスしたアドレスをもとに処理を割り振るための機能です。

routes/web.php

Route::get('tasks', 'TasksController@index');

例えば、上記のように書くとGETでルートパスにアクセスした際に
TasksControllerというコントローラのindexメソッドが実行されることを表しています。

モデル

モデルは、DBからデータを取得する処理が書かれています。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
    //
}

中身は空ですが、これでDBのtasksテーブルと紐付けることができます。

createやupdateなどの処理を実装した際は、 初期設定のままだとテーブルのどのカラムにも値を挿入することが出来てしまいますが、
fillableguardedを使うことで、こちらが意図していないカラムへの挿入を防ぐことが出来ます。
fillableプロパティには、挿入したいカラムを
guardedプロパティには、挿入したくないカラムを
指定することができます。

class Task extends Model
{
    protected $fillable = ['title', 'content'];
}

今回の例だと、title,contentはユーザーが値を自由に挿入するカラムなので、fillableを使っています。

コントローラ

コントローラとは、モデルとビューの橋渡しをする役割をしています。

app/Http/Controllers/TasksController.php

class TasksController extends Controller
{
    public function index()
    {
        $tasks = Task::all();
        return view('tasks.index', compact('tasks'));
    }
}

これはTaskモデルを使って、DBからデータを取得しビューに渡す処理をしています。

ビュー

ビューは画面表示を担当する箇所です。 コントローラーで運んできたデータを使って画面を完成させます。 ビューには、bladeというLaravelのテンプレートエンジンを使用します。 bladeはビューのなかに直接PHPを記述することもできます。 基本的にはresources/viewsディレクトリの中に設置します。

resources/views/task/index.blade.php

<html>
<head>
  <title>タスク一覧画面</title>
</head>
<body>
<h1>タスク一覧</h1>
<table>
  <tr>
    <th>タスク名</th>
    <th>内容</th>
  </tr>
  @foreach ($tasks as $task)
  <tr>
    <td>{{$task->title}}</td>
    <td>{{$task->content}}</td>
  </tr>
  @endforeach
</table>
</body>
</html>

まとめ

以上で、ユーザーのブラウザにサイト画面が表示されるまでの流れを追うことができました。 まとめると、

  1. ブラウザのURLによってルーティング処理を行う
  2. 該当のコントローラでDBからの情報を取得するようモデルに指示
  3. モデルでDBからデータを取得
  4. コントローラがモデルで取得したデータをビューに渡す
  5. ビューでユーザーの画面に表示

となります。

次回以降の投稿では、

  • ビューの部分をLaravelに置き換える
  • 生成、更新処理の流れ
  • ユーザー認証

などの内容をアウトプットできればなと思います。

さいごに

現在、株式会社SCOUTERでは、エンジニア、デザイナーの募集をしております。

興味のある方は、是非下記からご応募お願い致します!

www.wantedly.com

www.wantedly.com

www.wantedly.com

参考資料

Vue.jsを1年触ったのでオススメパッケージを紹介

はじめに

こんにちは株式会社SCOUTERでエンジニアをしているhirokinishizawaです。 業務では、SARDINEという人材紹介会社向けの業務管理システムを開発しています。

前回プログラミングを初めてから1年が経ったので「1年間のプログラミングを通して得た3つの教訓」というブログを書きました。

1年間実務だけやってきて自分が得た教訓をプログラミングを始めたばかりの方や、これから始めてみたいと思っている方に共有できればという思いで書いた記事になっています。

techblog.scouter.co.jp

今回は1年間Vue.jsを触ってきて自分がおすすめだなと思ったパッケージについて紹介していきたいと思います。

紹介するパッケージ一覧

  • Vue.Draggable

github.com

  • vue-social-sharing

github.com

  • vue-carousel

github.com

  • vue-star

github.com

こちらの4つについて話していこうかと思います。

導入方法はすべて定番のyarn add [package-name]npm install [package-name]で導入できます。

Vue.Draggable

以前Vue.Draggableを業務で扱う機会があったのでその時にブログを書きました。ドラッグ&ドロップでリストを並び替えすることをお手軽に実装できるパッケージになっています。

techblog.scouter.co.jp

業務で扱った時は横の移動だけではなく縦の移動もあるため縦の順番もデータとして持っておく必要がありデータベースの設計を慎重に行わなければいけませんでした。Vue.Draggableでドラッグ&ドロップをした時にどのようなデータを受け取ることができるのか把握してから設計を行えば横移動も縦移動も問題なく動かすことが出来るかと思います。

vue-social-sharing

vue-social-sharingとfont-awesomeを導入することでソーシャルボタンを簡単に設置できます。

<template>
  <social-sharing
    url="https://twitter.com/hiroki_2438"
    title=" タイトル記載"
    description="説明文を記載してください"
    hashtags="Vue.js"
    twitter-user="hiroki_2438"
    inline-template
  >
    <div>
      <network network="facebook">
        <i class="fa fa-facebook-official"></i>
      </network>
      <network network="twitter">
        <i class="fa fa-twitter"></i>
      </network>
    </div>
  </social-sharing>
</template>

<script>
import SocialSharing from "vue-social-sharing";

export default {
  components: {
    SocialSharing
  }
}
</script>

f:id:hiroki-nishizawa:20190419033835p:plain

networkタグのnetwork属性を変更することよりソーシャルメディアを変更をすることができます。

今回facebooktwitterだけしか実装していませんが他にも

など。上記以外にもありますが、メインどころはこんなところでしょうか。

次にSocialSharingコンポーネントにpropsでtitleなどを渡していますが実際にコンポーネントで何を受け取っているのか調べてみました。

渡しているもの 説明 補足
url シェアしたいurlになります 何も指定しなければでソーシャルボタンが設置されているurlが指定されます
title タイトルになります 利用可能なのはemail,twitterになります
description 説明文です 利用可能なのはemail,LINE,SMS
quote facebook用のquoteになります facebookのみ使用可能
hashtags ハッシュタグです facebooktwitterのみ使用可能でfacebookは1つ目のみ使われます
twitter-user twitterのアカウントIDをいれてください twitterのみ使用可能

自分がよく使うのは基本的にfacebooktwitterなので十分だったのと、導入するだけで簡単に実装できるし以前aタグでやっていたときより簡潔で読みやすくなるのでおすすめです。

以前aタグでやっていた時

#facebook
<a class="fb btn" :href="`http://www.facebook.com/share.php?url=urlを記載`"
             onclick="window.open(this.href, 'FBwindow', 'width=650, height=450, menubar=no, toolbar=no, scrollbars=yes'); return false;">
    <img src="facebookのicon画像">
</a>

#twitter
<a :href="`https://twitter.com/intent/tweet?text=タイトル&url=urlを記載`" target="_blank">
    <img src="twitterのicon画像">
</a>

vue-carousel

vue-carouselはカルーセルを簡単に実装できレスポンシブにも対応していてとても使いやすいUIコンポーネントです。

<template>
  <Carousel
    :per-page="1"
    loop=true
    :navigation-enabled="true"
    navigation-prev-label="〈"
    navigation-next-label="〉"
    touchDrag=true
    :speed="1000"
  >
    <Slide v-for="(slide, key) in slides" :key="key">
      <span>{{slide}}</span>
    </Slide>
  </Carousel>
</template>

<script>
import { Carousel, Slide } from "vue-carousel";

export default {
  components: {
    Carousel,
    Slide
  },
  data() {
    return {
      slides: ["slide1", "slide2", "slide3", "slide4", "slide5", "slide6"]
    };
  }
};
</script>


f:id:hiroki-nishizawa:20190419053208p:plain

上記のCarouselコンポーネントにpropsで渡してしているのは

  • per-page
    • 各ページに表示されるスライドの最大数
  • loop
    • 最後に到達したときにカルーセルをループさせるためのもの
  • navigation-enabled
    • navigation-prev-labelとnavigation-next-labelを使用できるようにするもの
  • navigation-prev-label
    • ナビゲーションの前に戻るボタンのテキスト
  • navigation-next-label
    • ナビゲーションの次に進むボタンのテキスト
  • touchDrag
    • タッチドラッグを出来るようにするもの
  • speed
    • スライドする時のスピードを調節するもの

それぞれこのような設定になっています。

今回使っているものの他に autoplay autoplayDirection autoplayHoverPause autoplayTimeoutのように時間で自動的にスライドを出来るようにするための設定だったり、スマホ用にスワイプで切り替わるようにするための設定だったりとカルーセルの実装をするために必要なものを簡単に実装できるのがとてもおすすめできるポイントだなと思います。

vue-star

twitterのいいねみたいなアニメーションを簡単に実装できるUIコンポーネントになっています。

<template>
  <vue-star color="#F05654">
    <i slot="icon" class="fa fa-heart"></i>
  </vue-star>
</template>

<script>
import VueStar from "vue-star";
export default {
  components: {
    VueStar
  }
};
</script>

f:id:hiroki-nishizawa:20190419195526g:plain

他にもcolorのカラーコードを変えて色を変更したり、animateという属性を使ってanimationのクラスを入れることによって違う動きができたりします。 自分は使っているのですがanimate.cssを入れることでより簡単にanimationの幅を広げることができます。

<template>
  <div class="vue-stars">
    <vue-star animate="animated wobble" color="#0000ff">
      <i slot="icon" class="fa fa-heart"></i>
    </vue-star>
  </div>
</template>

f:id:hiroki-nishizawa:20190419195233g:plain 自分がプログラミングを初めて半年とかの時に業務でお気に入り機能を実装することになったのですが、当時デザイナーの意向でやりたいという話になりcssで出来るっぽいってとこまでわかったのですが工数的にやらないという意思決定になりました。そのときにこれを知っていたら実装できたのではないか。と思っております。。。

このようなアニメーションが必要な時にほんと簡単に実装できるのでとてもおすすめです。

まとめ

今回は数あるパッケージの中から自分が実際に使い個人的にいいなと思ったパッケージを紹介しました。もちろん他にもたくさんのパッケージがあります。今回紹介したものと似たようなパッケージ、自分が知らない便利なパッケージ、絶対業務では扱わないけど面白そうなパッケージ。たくさんのVue.jsのパッケージがあり、パッケージをまとめてくれている方も多いので試しに使ってみてはいかがでしょうか。

自分の場合はドラッグ&ドロップをしたいだったり、カルーセルを実装したいだったりしたときにVue.jsを冒頭に付けて検索をした結果触ることになったり、まとめてくれているサイトで面白そうってだけで触ったりしました。

最後に

弊社では事業・サービスが成長していくにあたってメンバーを増やしていきたいと思っています。

興味のある方は下記からご応募いただくか、@hirokiにご連絡ください!!

www.wantedly.com

www.wantedly.com

www.wantedly.com

E2Eテストを導入して自分を救う (TestCafe編)

こんにちは、自意識過剰な正義のヒーローでお馴染みの株式会社SCOUTERの石岡 将明( @masaakikunsan )です。

先月のブログで、フロントにおける unit test についてブログを書いている人がいたので、今回は E2E テストについて書いていこうかなと思います。

E2E テストとは

E2E (End to End)テストとは Web ブラウザを通して一通りの処理をテストすることです。

今回のデモで作成するものを例として挙げます。

  1. ユーザー登録画面を表示
  2. 名前を入力
  3. bioを入力
  4. 送信ボタンをクリック
  5. ユーザー一覧ページに遷移
  6. ユーザー一覧に追加したユーザーが追加されている

なぜ E2E テストが必要なのか

みなさんはリリース前にテストをして最終確認をすると思います。 その際に全ページの UI の確認と挙動が想定どおりになるかどうかのテストを毎回していたらかなり時間の無駄です。

そこで、 E2E テストをすることで手を動かさずに全ページの UI と挙動のテストをすることができ、時間もコストもかなり下がり生産性があがるでしょう。

また、このような経験はありませんか?

実装した箇所以外のテストが漏れていてリリースしたらバグがあった。みたいな E2E テストを実行すれば基本的にこれは防げます。

全画面のテストを自動でやることで、影響範囲の漏れもなくなり品質担保にも繋がります。

つまり、 E2E テストはコストを下げる為だけでなく自分を救うことにも繋がります。

Nuxt.js に E2E テストを導入しよう

json-server を追加する

今回はテストに使う mock サーバーとして json-server を利用します。

さっそく導入していきます。

$ yarn add -D json-server

次に json を追加していきます。

db/db.json を追加して以下を記載します。

{
  "user": [
    {
      "id": 1,
      "name": "masaakikunsan",
      "bio": "自意識過剰な正義のヒーロー"
    }
  ]
}

最後に json-server を実行するために package.json に scripts を追加しましょう。

"server": "json-server --watch db/db.json --port 4000"

これで、 $ yarn server を実行し、 localhost:4000/user にアクセスすると db.json に記載したデータが表示されるでしょう。

f:id:masaakikunsan:20190416172936p:plain

次に、ユーザー一覧ページとユーザー作成ページを作っていきます。

ユーザー一覧とユーザー作成ページ

下記のようなページを作成しました。

f:id:masaakikunsan:20190416185539p:plain

f:id:masaakikunsan:20190416185657p:plain

コードはURLを載せて置くのでみてください。 github.com

TestCafe の導入

E2E テストですと、Puppeteer がかなり主流になってきていますが今回は TestCafe を使います。 理由としては、ブラウザを指定することでそのブラウザでのテストが可能だからです。

あと Puppeteer よりドキュメントが読みやすくて個人的に好きというのもありますw

まぁ他にも理由はあるので自分で調べてみてください。

devexpress.github.io

それではさっそく導入していきましょう。

$ yarn add -D testcafe

次に TestCafe を実行するために package.json に scripts を追加しましょう。

"e2e": "testcafe chrome test/e2e/*.js --speed 0.5"

speed を指定することで E2E の実行スピードを指定できます。

それでは、テストコードを書いていきましょう。

test/e2e/test.js を作成し下記コードを記載していきます。

import { Selector } from 'testcafe'

fixture('ユーザー追加').page('http://localhost:3000/create')

const customDataAttribute = name => `[data-test='${name}']`

test('必要項目を入力後、送信して遷移先を確認', async t => {
  const userName = await Selector(customDataAttribute('name'))
  const userBio = await Selector(customDataAttribute('bio'))
  const submitButton = await Selector(customDataAttribute('submit-button'))

  await t
    .setNativeDialogHandler(() => true)
    .typeText(userName, 'test')
    .typeText(userBio, 'bioだよ〜')
    .click(submitButton)

  const tableUserName = await Selector(customDataAttribute('user-name')).nth(-1)
    .innerText

  await t.expect(tableUserName).eql('test')
})

Selector は、テスト内の要素を識別するものです。 ここでは、data属性を定義しそれを元に要素を識別しテストを実装していきます。

それでは実行していきましょう。

テストで正しく挙動していることが確認できました。

scripts の testcafe の横の chromesafari にすれば safari が起動しますし、 firefox にしたら firefox が起動します。 これでブラウザテストの時間もかなり削減できます。

まとめ

E2E テストでの実装例を紹介していきました。いかがだったでしょうか?

E2E を実際のプロダクトにいきなり導入するのはコスト的にも難しいでしょう。 ただ、E2Eテストを絶対にバグっててはいけないところだけ導入するだけでもかなりテストの工数も下がり良いでしょう。

ずっと、言っていますが自分を助けることになります。

ちなみに、僕はフリーランスのときに実装した箇所がクレカ決済の箇所に影響が及んでいてクレカ決済が死ぬっていうバグを起こして以来テストはまじ大事自分を助けるって気持ちになっています。

現在、back check チームでは、エンジニアの募集をしております。 僕と一緒にフロントエンドを朝まで語り尽くしたいフロントエンドエンジニアやレベルの高いフロントエンドチームと最高のプロダクトを作って行きたいサーバーサイドエンジニアは是非ご応募お願いいたいします!

www.wantedly.com

www.wantedly.com

[Nuxt.js] middleware で外部リソース取得処理を共通化

こんにちは!

SCOUTER社でエンジニアをしている匠平@SCOUTER(@show60)です。

開発を進めるにつれ page component も増えていきますが、複数の page component で同じ外部リソースが必要なことがあります。

同じ処理を行っている場合は処理をまとめちゃいたいですね。

そんなときのために、 middleware を使った処理の共通化についてお話しします。

fetch で外部リソースからデータを取得する

page component 内で使われるデータを外部リソースから取得したいとき、 Nuxt.js では page component 内で fetch を使うことでこの処理を行うことができます。

また、この fetch は、取得したデータを Vuex store に格納することを前提としています。

これにより、その page component 配下にある component でも Vuex store に格納されたデータを扱うことができるようになります。

下図内で、 ...fetches data before rendering page と記述してあるとおり、 page component で記述した fetch はその page component が読み込まれる度、そのレンダリングの前に発動します。

複数の page で使われている処理を共通化

複数の page compoent において、fetch で同じデータを取得しているとき共通化を考えます。 どこからでも呼び出せる処理の実装を考えたときに、手段として mixins と middleware があります。 fetch は page component でしか動作しないため、 mixins と middleware 上では、他の方法を考える必要があります。

mixins

下記の mixins を page component で呼び出すと page component 内で sample という data を使用することができます。 created のタイミングでデータ取得処理を発動させ、それを data に挿入しています。

// mixins/sampleMixins.js
export default {
  data: () => {
    return {
      sample: []
    }
  },
  created() {
    this.getSamples()
  },
  methods: {
    async getSamples() {
      this.sample = await this.$axios.$get('/api/sample')
    }
  }
}

ただし、 page component 内ですでに sample という名前で data が定義されている場合、そちらが優先されてしまいますので注意してください。

参考: Option Merging

外部リソースからデータを取得する処理自体は共通化することができましたが、この page component 配下で使用するためには props でデータを渡していく必要があります。

middleware

middleware 内では下記のようにすることで、外部リソースへ接続し、 Vuex store に値を格納することができました。

// middleware/index.js
export default ({ store }) => {
  // すでに store にデータが格納されている場合は再取得を行わない
  if (store.state.sample) {
    return
  }
  store.dispatch('getSamples')
}

middleware はページ遷移する度に呼び出されるため、必要なデータがすでに Vuex store に存在しているのであれば再取得の処理を行わないよう記述してあげるといいですね。

middleware で共通化する上で注意すること

middleware を介して Vuex store にデータを格納できたのですが、適さないデータというのもあります。

Nuxt.js の SPA ではページ遷移しても Vuex store のデータをそのまま保持しています。そのため、利用中に書き換わる頻度が高いデータにおいては正しいデータを表示してくれない事態が起きます。

例えば頻繁な更新がないと思われるユーザー情報や、部署名と部署 ID の対応表といったようなデータの取得に使用するほうがいいでしょう。 ユーザー認証されているかを全 page に渡って確認したい場合もこのように処理します。

最後に

SCOUTER は先日、新サービス back check を正式リリースいたしました!

これからたくさんのお客様に最高のプロダクトを届けていくため、一緒に開発を進めていくエンジニアの募集をしております。

ぜひご興味を持ったかたはご連絡ください!

www.wantedly.com

www.wantedly.com

AWS SystemManagerを使って、簡単にサーバー監視やIDS等を導入する

こんにちは kotamat です。 最近は社内セキュリティの向上に取り組んでおり、その一環でAWS System Managerを導入してみたら非常に簡単にいろいろなものがセットアップできたので、そちらの紹介をさせていただきます。

EC2へのソフトウェアインストールの課題感

複数のEC2インスタンスが必要かつ、どのインスタンスにもインストールするソフトウェアがある時、皆さんはどうしているでしょうか? 予めそのサーバーに必要なソフトウェアがわかっている場合はインストールした状態でAMIに固め、それをAutoScalingのAMI設定にしたり、EC2立ち上げ時にそのAMIベースに起動することによってすべてのインスタンスに反映することができるかと思います。

ただ、すでにインスタンスが立ち上がっている場合、それぞれのインスタンスにわざわざsshで入ってインストールしたり、AnsibleやChefを使って一括インストールをしていたかと思いますが、前者はインスタンス数が増えてきたときに対応が難しく、後者に関してはインフラ構成にもよりますが、踏み台の設定が必要だったり、構成管理ツール用に書き換える手間が発生します。

そういった中でAWSのSystemManagerは上記を解決するツールとして有用だったため、今回使用してみることにしました。

SystemManagerって何?

AWS Systems Manager は、Amazon EC2 インスタンス、オンプレミスサーバーと仮想マシンや他の AWS リソースを大規模に設定および管理する機能のコレクションです。Systems Manager には、AWS リソース間で運用データを簡単に一元化し、タスクを自動化できる統一されたインターフェイスが含まれています。Systems Manager はインフラストラクチャで運用上の問題を検出して解決するための時間を短縮します。Systems Manager は、インフラストラクチャのパフォーマンスと設定についての詳細を提供し、リソースとアプリケーションの管理を簡素化することで大規模なインフラストラクチャの運用と管理を簡単にします。

先日の発表で注目されたSessionManagerを始め、たくさんの機能を内包している物となっており、EC2やオンプレサーバーの一括管理に向いている物となっています。

今回はその中でもRun Commandを使ったツールのインストール方法について紹介させてもらいます。

RunCommand

ユーザ任意のターゲットインスタンスに対して、一括でコマンドを実行できるものです。

Dockerのコマンドを一括実行する AWS-RunDockerAction や、AmazonInspectorのエージェントを一括でインストールする AmazonInspector-ManageAWSAgent など便利コマンドももちろんありますが、 AWS-RunShellScript といった、シェルスクリプトを実行してくれるコマンドもあります。 こちらはsudo権限を付与できる任意のコマンドを打つことができるため、今回の背景のような外部ツールの一括インストールには非常に向いています。

導入方法

EC2のロールにIAMポリシーを付与する。

まず、AWS SystemManagerが管理対象としてEC2インスタンスを認識できるようにします。 AmazonLinux系であれば、最初からデーモンプロセスがインストールされている状態で起動しますので、 EC2ロールに対して arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM を付与するだけで大丈夫です。

EC2にタグをつける

SystemManagerのRunCommandでは、インスタンスのタグを指定して一括実行が可能なので、 タグをつけて運用していない場合は予めタグを付けておきましょう。 Env:production などのタグを予め指定しておく形をおすすめします。

RunCommandを設定する。

AWS SystemManager > Run Commandからコマンドの実行を選択します。

f:id:kotamat:20190401075406p:plain

コマンドの中から AWS-RunShellScript を選択します。

f:id:kotamat:20190401075503p:plain

コマンドのパラメータのところでは、任意のシェルスクリプトを記述します。 SaaS型のサーバー監視ツールやIDSでは公式でスクリプトを提供していることが多いと思いますので、そちらを記載します。

f:id:kotamat:20190401075611p:plain

ターゲットは手動での指定かタグでの指定ができます。 手動で指定を行ってもいいのですが、本番環境のみインストールしたいというパターンも多いかと思いますので、 Env:production などのタグを予め指定しておいて、そこにインストールする形をおすすめします。

f:id:kotamat:20190401080150p:plain

出力オプションでは、コマンドの結果の出力先を指定できます。 コマンドの出力を2500文字以上出力したい場合はS3のバケット指定を、CloudWatchLogsで確認できるようにしたい場合は、CloudWatch出力にチェックし、設定を行います。 CloudWatchに関しては、デフォルトで /aws/ssm/AWS-RunShellScript に書き込まれるので、それで問題なければロググループ名を空白にします。

f:id:kotamat:20190401080240p:plain

SNS通知では、コマンド完了等のステータスに関する通知を受け取る設定ができます。

のいずれかのステータスを受信したい場合は設定しましょう。

f:id:kotamat:20190401080635p:plain

Run Commandの実行

あとは実行ボタンを押すだけです。 実行後はコマンド履歴の方に反映されます。

f:id:kotamat:20190401081136p:plain

コマンドの詳細では、実行したインスタンスの一覧が表示されます。

f:id:kotamat:20190401081301p:plain

そして、インスタンスを選択し 出力の表示 を押すと、その実行されたコマンドの標準出力を確認することができます。

f:id:kotamat:20190401081500p:plain

これでコマンドの実行は完了です。

まとめ

今回はSystemManagerの中でもRunCommandに焦点をあてて紹介させてもらいました。 RunCommandを用いることで、単発コマンドを複数のインスタンスに一括で実行することが簡単になるため、 すでに立ち上がっているインスタンスへ監視ツールを導入したいときや、IDSなどのセキュリティツールを導入したいときなどに活用することができるかと思います。

最後に

SCOUTERではエンジニア、デザイナーともに募集しております! 新規事業、絶賛グロース中の事業ともにLaravel, Vue.jsで開発しておりますので、 興味のある方はお声がけください!

体験副業もはじめました!

www.wantedly.com

www.wantedly.com

www.wantedly.com