RareJob Tech Blog

レアジョブテクノロジーズのエンジニア・デザイナーによる技術ブログです

マルチステージビルドで環境毎のLaravelイメージを作る

はじめに

こんにちは、サービス開発チームの加々美です。初投稿になります。

先日直属の上司の方に「最近2日に1回はカレー食べてます」と謎の共有をしたところ、「疲れてるんじゃないですか?」と言われました。 私はただカレーにハマってるだけだと思っていますが、もし週に何回もカレーを食べてしまうという方は注意が必要かもしれません。

早速ですが本題に入っていきたいと思います。

Dockerイメージを作る際に開発環境と本番環境でインストールしたいパッケージや設定が異なることがあると思います。

一方で全く異なるかというとそんなことはなく、基本的には同じで開発時のみデバッグツール(PHPだとXdebug)を利用できるようにしたい、といったケースが多いです。

今回はLaravelの環境毎に利用できるDockerイメージ作成時の知見についてまとめた内容になります。

マルチステージビルドに関する記事は多いですが、意外とLaravelでの記事がなかったためこの機会にまとめました。

今回のフォルダ構成

今回のサンプルは以下のフォルダ構成で作成しています。 srcにはLaravelアプリケーションのファイルを置いてます。

├── docker
│   ├── app
│   │   ├── Dockerfile
│   │   └── docker-php-ext-xdebug.ini
│   └── web
│       ├── Dockerfile
│       └── default.conf
├── docker-compose.yml
└── src

マルチステージビルドとは

Docker 17.05から利用できるようになった機能で、マルチステージビルドが登場する前は次に説明するDockerfileを複数作成するなど共通の定義を利用できませんでした。 マルチステージビルドを利用することでベースとなるイメージを作成し、それを再利用することによりイメージ毎に不要なファイルが含まれることを防ぐことができイメージサイズの削減が可能になります。

matsuand.github.io

マルチステージビルドを使用しない場合

マルチビルドステージを利用しない場合はDockerfileを複数作成する方法がありますが、Dockerfile毎にそれぞれで定義する必要があるため共通で使用する箇所が多い場合でも全て記載しないといけません。

Dockerfileを別々で定義する場合、変更する度にそれぞれに対して変更を加える必要があり管理が煩雑になります。

開発用のイメージのビルド

何も考えずにdocker/app/Dockerfileを作成すると以下になります。

FROM composer:latest AS composer

FROM php:7.4-fpm-alpine

COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN set -eux \
  && apk update \
  && apk --no-cache add \
    git \
    oniguruma-dev \
    libzip-dev \
    zip \
  && docker-php-ext-configure zip \
  && docker-php-ext-install pdo_mysql mbstring zip \
  && composer config -g repos.packagist composer https://packagist.jp \
  && composer global require hirak/prestissimo \
  && apk --no-cache add \
    autoconf \
    gcc \
    g++ \
    make \
    openssh-client \
  && pecl install xdebug \
  && docker-php-ext-enable xdebug

COPY ./src /var/www/

上記の中で開発環境用に追加するパッケージはこちらです。

  && apk --no-cache add \
    autoconf \
    gcc \
    g++ \
    make \
    openssh-client \
  && pecl install xdebug \
  && docker-php-ext-enable xdebug

RUN内で2度apk --no-cache addを行なっていますが、本番用のイメージと比較しやすいようにあえてこのように記述しています。

このDockerfileをビルドしてみます。

docker build . -f docker/app/Dockerfile -t sample1

docker imagesで作成されたイメージを確認してみます。

REPOSITORY     TAG       IMAGE ID          CREATED            SIZE
sample1        latest    536e1516fffb      2 hours ago        378MB

本番用のイメージのビルド

ビルドするファイルの内容は以下になります。

FROM composer:latest AS composer

FROM php:7.4-fpm-alpine AS builder

COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN set -eux \
  && apk update \
  && apk --no-cache add \
    git \
    oniguruma-dev \
    libzip-dev \
    zip \
  && docker-php-ext-configure zip \
  && docker-php-ext-install pdo_mysql mbstring zip \
  && composer config -g repos.packagist composer https://packagist.jp \
  && composer global require hirak/prestissimo

COPY ./src /var/www/

こちらもdocker imagesで作成されたイメージを確認してみます。

REPOSITORY  TAG       IMAGE ID          CREATED           SIZE
sample2     latest    dbb97bb45402      9 seconds ago     136MB
sample1     latest    536e1516fffb      2 hours ago       378MB

Xdebug関連のインストールがないだけでイメージサイズが半分以下になっているのがわかりますね。

マルチステージビルドを使う

docker/app/Dockerfileは以下になります。

FROM composer:latest AS composer

FROM php:7.4-fpm-alpine AS builder

COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN set -eux \
  && apk update \
  && apk --no-cache add \
    git \
    oniguruma-dev \
    libzip-dev \
    zip \
  && docker-php-ext-configure zip \
  && docker-php-ext-install pdo_mysql mbstring zip \
  && composer config -g repos.packagist composer https://packagist.jp \
  && composer global require hirak/prestissimo


FROM builder AS dev

RUN set -eux \
  && apk --no-cache add \
    autoconf \
    gcc \
    g++ \
    make \
    openssh-client \
  && pecl install xdebug \
  && docker-php-ext-enable xdebug

COPY ./src /var/www/

FROM builder AS prod

COPY ./src /var/www/

簡単に解説していきたいと思います。

FROM php:7.4-fpm-alpine AS builderの箇所で共通で利用できるステージを定義しています。

devprodのステージを定義する際にbuilderステージを利用します。

builderの利用方法はFROM builder AS devのように利用します。

devではデバッグ用のパッケージをインストールしていますが、prodではbuilderをそのまま利用しています。

ビルドする際は--target devのようにビルドしたいステージをオプションで指定します。

それぞれビルドします。

docker build . docker/php/Dockerfile -t sample3 --target dev

docker build . docker/php/Dockerfile -t sample4 --target prod

実行結果を確認すると以下のようになりました。

REPOSITORY    TAG       IMAGE ID          CREATED              SIZE
sample4      latest     39bd6a456c9d      29 seconds ago       136MB
sample3      latest     e1bee9d50280      About a minute ago   378MB

マルチステージビルドを利用しないパターンと同じイメージがビルドできました。

弊社では主にAWSを使用しており、ECSへの移行も考慮しているので各環境毎にビルドしたイメージをECRにpushする場合などは--targetでステージを指定することで対象のDockerイメージをビルドすれば良さそうです。

また、ステージを指定してビルドした場合は、対象ステージのみビルドされます。

つまり、prodを指定してビルドする際はdevはビルドされません。

docker-composeでステージを指定して利用する

最後にdocker-composeで指定する方法について解説したいと思います。

今回使用したdocker-compose.ymlはこちらでです。

version: '3.7'
services:
  app:
    build:
      context: .
      dockerfile: ./docker/app/Dockerfile
      target: dev
    volumes:
      - ./src:/var/www
      - ./docker/app/docker-php-ext-xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
  web:
    build:
      context: .
      dockerfile: ./docker/web/Dockerfile
    ports:
      - "8000:80"
    volumes:
      - ./src:/var/www
      - ./docker/web/default.conf:/etc/nginx/conf.d/default.conf

ステージを指定している箇所はtarget: devの箇所です。

意外と今までやったことがなかったですが、簡単に指定できました。

あとはdocker-compose upを実行し、立ち上がったらdocker-compose exec app shでコンテナ内に入り、composer create-project laravel/laravel .を実行すればブラウザで確認できるようになります。

おまけ

サンプルのDockerfile内でcomposerに関して以下のように利用していました。

FROM composer:latest AS composer

COPY --from=composer /usr/bin/composer /usr/bin/composer

これは外部イメージをステージとして利用する方法です。

https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/multistage-build/#use-an-external-image-as-a-stage

検証できていないですが、この方法を使用すればbuilderで定義したイメージをCIでECRなどにあげておき、開発者はそこからステージとして開発環境に利用できるのかも?と思ったりしました。

まとめ

今回はマルチステージビルドを利用したLaravelのDockerイメージ作成について説明しました。

もっと良い使い方あるという方はコメント頂けると嬉しいです。

思ったより記事を書くのに時間がかかったので今夜はカレーを食べたいと思います。(実は5日連続。。)

UMLをコードベースで管理する

さて、ジャンボです。本当はGOTO( Ghost of Tsushima Omoshiroi-zo )という話を書きたいところですが大人しくテックブログを始めようと思います。今日はPlantUMLの話をします。

PlantUMLの導入

みんな好きですよね、設定しましょう

1. 必要なツールを落とす

brew install graphviz
brew install plantuml
brew install maven

2. vscode拡張機能を入れる

  • PlantUML

これだけも利用を始めることができます。xx.pu というファイルを作り、Preview Current Diagram を実行すればUMLを表示することが可能です。ただxx.pu のファイルを画像に変換するときにこの拡張機能はリモートのサーバを見ているのでレンダリングがかなり遅いです。そのためローカルのマシン上にPlantUMLのサーバを立てます。

3. ローカルでPlantUMLサーバを動かす

git clone https://github.com/plantuml/plantuml-server.git
cd plantuml-server
mvn jetty:run -Djetty.port=10001

jettyのデフォルトのportが他と被りやすいので明示的にport指定します。 このプロセスが動いていないとレンダリングには失敗します、起動は少し時間がかかります

4. 拡張機能の設定変更

ここから f:id:jumbos5:20200721093242p:plain

ここを変更 f:id:jumbos5:20200721093222p:plain

この辺を設定する。 RenderとServerの値を変更して下さい。

5. markdownでプレビューする

.md内でプレビューしたい場合は上記の設定を終了後に#4の設定で対象とする拡張子指定で md を指定できるので、ここから設定しておくと設定されたローカルサーバを参照してマークダウン内でもプレビューされます。

f:id:jumbos5:20200721093624p:plain

tips

お手軽に試したいようであればこちらのプラグインでもプレビュー可能です。ただ外部サーバにリクエストしているようなのでレンダリングが遅かったり、またセキュリティ上も微妙かなと思います。 shd101wyy.github.io

また前回弊社のいとうさんが記事を書いてくださり、GitLabでPlantUMLをプレビューできると書いてくれています。これは便利なんですが、!include 機能がGitLabでは現在まだ利用できないように見えるので、これはただ期待するばかり。

用法用量を守って楽しくUMLしましょう。

Figmaでレアジョブコーポレートサイトのデザインをリニューアルした話

こんにちは、デザイナーのキョウです!
2回目の投稿ですが、ついこの前リニューアルしたばかりのレアジョブコーポレートサイトの話をちょっとしようかなと思います!

リニューアルの背景


まずは、今回のリニューアルの背景としては、

  • デザイン、コード共に古い
  • デザインが端末ごとに最適化されていない(レスポンシブ対応がされていない)
  • 運営更新に限界を感じている

会社のイメージアップと今後のビジョンのために、そろそろリニューアルしたいねという話になりまして、今回のリニューアルプロジェクトが開始したわけです。

作成のボリュームは、PCデザイン画面38ページ、スマホデザイン画面38ページといった感じで、構築はWordPress上で、制作期間は2ヶ月ちょっとという短い期間でした。

制作の過程について


今回のリニューアルプロセスとして、こういった感じで進めていました。

f:id:kyou_setsu:20200702152032p:plain

デザイン作成からサイト公開するまでの納期時間は短かったため、今回のデザイン作成は自社で、コーディングとサイト構築はパートナー会社に頼む形になりました。

そこで、今回もFigmaというデザインツールが大活躍してくれました!

まずは何がよかったというと、フィードバックのしやすさ、パートナー会社とのコミュニケーションのとりやすさ、自社の確認者(広報の担当者)とデザイナー(私)とサイト構築作業者(パートナー会社)の三者の間の情報共有はすべてFigma上で実現することができ、確認作業はとてもスムーズで、時間短縮にはかなり役に立っていたと感じましたね。

今までなら、パートナー会社とやり取りする際は、デザインデータを渡したり、デザイン修正する度に新しいデザインデータを書き出して渡したり、また修正指示を出す時は、画面のキャプチャをいっぱい撮って修正箇所のコメントを書いたり、指示書を作ったり、メールで送ったり、かなりめんどくさかったんですが、今回はこのようなやり取りをすべてFigma画面上で実現することに当たって、デザイン画面をリアルタイムで共有し、デザインの修正が発生してもURLが変わらないので、広報の担当者とパートナー会社は常に最新のデザインが確認できます。

また、Figmaのコメント機能を利用すれば、パートナー会社に修正してほしいところを画面上に直接指示を出すことができ、パートナー会社も修正指示にすぐ気付いてくれたり、修正のレスポンスはとにかく早いです! お互いに質問があった時も、すぐコメントで書いたり返信したり、効率はとてもいいですね!

実際にFigmaのコメント機能を利用して修正依頼のやりとり例として:

f:id:kyou_setsu:20200703154442p:plain

新しいデザインのあれこれ


そして完成した新しいコーポレートサイトはこちらです!
トップページはこんな感じに変わりました↓

f:id:kyou_setsu:20200701160510p:plain


■今回のリニューアルで特に意識して力を入れたポイント

今回のリニューアルはなんと言って、今までと全然違うイメージを与えたくて、
初めてこのサイトを訪れる人に印象が残りやすいように、初めてではない方にイメージアップとインパクト力を感じるように、おしゃれ感とスタイリッシュ感の演出に意識してデザインを作成しました。
例えば、今流行りのグラデーションカラーを取り入れたり、文字サイズを大きめにし、メリハリを付けたり、コンテンツ間の余白を広めにとったり、シンプル且つ見やすいデザインに仕上げました。

また色合いの調整について、レアジョブの代表色は元々薄い黄緑で、そのまま使うと、結構見づらかったり、ユーザービリティの悪いページになってしまうため、いかにブランドカラーのイメージを活かしながらバランスの良い色合いに仕上げるために、いろいろ試行錯誤を重ねてきました。

f:id:kyou_setsu:20200701114400p:plain



■デザインで苦労した点について

サイト全体のページ数はそれなりに多く、また各ページのコンテンツ内容もそれぞれ違うので、分かりやすいレイアウトにするために、かなり悩みましたね。

プレスリリースなどのニュース系記事ページや、投資家情報を発信するためのIRページなど、情報量は多いため、細かくカテゴリー分けにしたり、各カテゴリーに移動しやすいようにページ内リンクを作ったり、いろいろ工夫をしました。
あとは、役員紹介ページの写真の統一感を出すため、役員陣の皆さまがかっこよくみえるように、写真のレタッチやレイアウトの調整を何度も行いました。

f:id:kyou_setsu:20200701120433p:plain

最後にちょっとした余談 (・ω・)


今回のリニューアルの話がきた時に、私の中ではかなりテンションが上がってました。何故なら、とてもやりがいを感じていたのと、せっかくなので攻めたデザインで行こうというワクワク感が、私の心の中でひっそり湧いてきたからです(笑)

初めてこのサイトを訪れた人には、この会社は明るくて、元気で、そしてチャレンジ精神旺盛だと思っていただけるよう、自分なりに精一杯レアジョブらしさを伝えようという想いで、今回のデザインリニューアルを行いました。

任意のサイトにあるaタグを別タブで開く

こんにちは。サービス開発チームのすずきです。

早速ですが、皆さんは外部リンクを別タブで開きたい派ですか?私は開きたい派です。 リンクを別タブで開くためにcommandを押しながらリンクをクリックするのですが、 毎回commandキーを押しながらクリックするのは少し手間です。 commandキーを押し忘れたら画面遷移してしまい、わざわざブラウザバックしなければいけません。

そこでChrome拡張機能であるScriptAutoRunnerを利用して、aタグのtarget属性に_blankを付与するようにしました。

github.com

利用方法は開発者のGithubに譲りますが、 以下のようにjsを記述することで、外部リンクを別タブで開くようにしました。

var anchors = document.getElementsByTagName('a');
for (var i = 0; i < anchors.length; i++) {
    var anchor = document.createElement('a');
    anchor.href = anchors[i].href;
    if (location.hostname !== anchor.hostname
        && anchor.href !== 'javascript:void(0);') {
        anchors[i].target = "_blank";
    }
}

では!

Airを使ったGo環境でのホットリロード

こんにちは。

つい先日誕生日だったのですが、昨今のアレコレのせいで独り寂しくお祝いしました。
アレコレが無ければきっと盛大にお祝いして貰えたはずだったのですが……
去年も一昨年もその前も独りでお祝いしたかもしれませんが、可能性は0では無いです。
サプライズパーティの準備をしていた方、大変申し訳ありません。
尚、私のカバンにはまだ若干の余裕があることだけはお伝えしておきます。

ホットリロード is 何?(実はライブリロード)

簡単にいうと「変更をすぐに反映してテストを行いやすくする機構」です。
修正がリアルタイムに反映されるためデバッグなどの作業が効率的に行えます。

実はホットリロードと言いつつ今回の話はホットリロードでは無いです。
何言うてるねんと言われそうですがGoは変更箇所の適用のため全体を読み直す為
「ホットリロード」ではなく「ライブリロード」になります。

  • 変更箇所だけ読み込んで反映するのがホットリロード
  • 変更箇所含めて全て読み込んで反映するのがライブリロード

と言うことだけ覚えておけば大丈夫です。
でも皆さんホットリロードと言ってる気がするのでどっちでもいい気がします。

伝わればいいのだ伝われば。

Go環境のホットリロードはRealizeが一番有名ですが、
現在ほぼ開発が止まっており、最新のmodulesを使う環境下ではエラーが出るなどから
代替を探して見つけたのがAirです。

とりあえずデフォルトで試す

何はともあれインストール

$ curl -fLo air https://git.io/darwin_air
$ chmod +x air
$ mv air /usr/local/bin 

Downloadしたairに実行権限をつけてパスが通っているところに移動させています。

次にテスト実行用の雑なsampleを用意

package main

import "fmt"

func main() {
    fmt.Println("Hello world!")
}

対象と同じディレクトリでAirを起動 f:id:dedekopon:20200626120731g:plain

Airの監視対象のファイルを修正する

package main

import "fmt"

func main() {
    fmt.Println("Hello world!")
    fmt.Println("Live reload!")
}

変更が反映され自動でリビルドされる f:id:dedekopon:20200626120739g:plain

まとめ

とりあえず動作確認しながらの開発には非常に便利そう。
実際はコンフィグを設定したりdocker上で動かしたり等もう一手間必要になりそうです。
コンフィグはexampleがあるのでそちらを参考に設定してみてください。

docker版 redash を最新版 v9 (ベータ版) へ upgrade する

redash の version 9 のベータ版が公開されました。

変更点がかなりあるので Changelog を見るだけでも面白いです。

V9 changelog (in master) by arikfr · Pull Request #4967 · getredash/redash · GitHub

個人的に興味深かった点が以下の 4つ です。

  • frontend は 100% React へ。( Angular、いままでありがとう!)
  • backend の job実行は Celery から RQ へ。
  • backend が Python 2 から 完全に Python 3へ。
  • data source に Amazon CloudWatch, Amazon CloudWatch Logs Insights が追加された。

と、今回の redash は frontend も backend も完全に刷新されており、今まであったメジャーアップデートの中でも一番のターニングポイントだと感じてます。

なにはともあれ version up

レアジョブでは redash が version 3.0 の時から使っており、定期的に version up をしていたのですが、1年半ほど前にversion 6 に上げてからは滞っておりました。

我々としては Amazon CloudWatch の連携が魅力に感じました。まずはベータ版というステータスなので社内の検証環境の redash を version upすることにしました。

redash は メジャー version up をすると redash 自体のデータを格納している postgres のスキーマ構造が変わることがよくあります。

version up するには redash で用意している migration tool を実行する必要があります。 ただし注意する必要があるのが

If you are currently running an instance of Redash prior to V7, do not upgrade directly to V8. Upgrade semantically to V7 first.

とあるように、 version が 7より下の場合は、まず先に version 7 へするようにと明記されています。 公式が提供している docker image を使いながら docker-compose.yml で定義する利用する docker image の version を一つづつあげていきます。

version 毎の docker image は以下公式ドキュメントをご覧ください。 https://redash.io/help/open-source/admin-guide/how-to-upgrade

例えば、version 6 から、version 7にあげる際は docker-compose.yml を以下のようにします。

before

services:
  server:
    image: redash/redash:6.0.0.b8537

after

services:
  server:
    image: redash/redash:7.0.0.b18042

その後

docker-compose run --rm server manage db upgrade

を行うと、server コンテナで migration tool が稼働し、redash の postgres に対しスキーマを変更しに行きます。 エラーが出なかったら

docker-compose up -d

で redash を起動してください。 login すると redash の version をブラウザ越しに確認することができます。 期待通りの version になっていることと、動作確認を行い問題なければ、先ほど行ったように docker-compose.yml で指定するイメージの version を上げて同様の作業を繰り返していきます。

version 9の起動

migration は成功しましたが、起動に失敗する事象に陥りました。

なぜ起動に失敗するのか原因を書く前に、 redash の構成をお話しする必要があると思います。 redash は 1つのコンテナイメージを使い複数コンテナを立ち上げ、それを相互に連携しあう事で動くようになっております。 https://github.com/getredash/redash/blob/master/bin/docker-entrypoint に定義してある server、scheduler、worker は最低限必要であり、 以下のように利用するコンテナイメージと、起動コマンドを定義して各コンテナを立ち上げる必要があります。

services:
  server:
    image: redash/redash:9.0.0-beta.b42121
    command: server
   (略)

  scheduler:
    image: redash/redash:9.0.0-beta.b42121
    command: scheduler
   (略)

  worker:
    image: redash/redash:9.0.0-beta.b42121
    command: worker
   (略)

この仕組み自体は以前と変わらないのですが今回、backend の仕組みが変わったことで、コンテナ を動かす上で必須となる環境変数が変わったことが原因のようです。

各コンテナに対して環境変数を書いていくと多くの場合冗長になってしまうので、公式の docker-compose.yml にある x-redash-environment のように環境変数の設定は1箇所にまとめ、各コンテナはそれを読み込むような作りにすると環境変数の漏れを防ぐことができるかもしれせん。

https://github.com/getredash/redash/blob/master/docker-compose.yml#L11

必要な環境変数が受け渡れば問題なく起動できます。

v9 を使うにあたってベンチマークスコアなどは取っておりませんが frontend も backend も生まれ変わったことで、レスポンスは体感で速くなったと感じています。

新しく追加された機能などについてはまた別の機会でお話しできればと思いますが、今回は docker版 redash を最新版へ upgrade する方法について記載させていただきました。

もちろん、今回はベータ版ですがGA になった場合は GA に update する予定です。

以上です。

Nuxt.jsプロジェクトにStorybookを導入する

こんにちは。APP・UXチームの大谷です。約1年ぶりくらいの投稿です。

最近は家にいることが多いので、ちょっと時間がかかる料理でもしてみよう。。
と餃子を皮から作ったりしています。餃子の皮を作る時は、お湯より水を使って練った方がモチモチ感がでて美味しいです。自分の好みにあった配合と焼き方を研究していきたい。

さて、今回は表題の通りNuxt.jsプロジェクトにStorybookを導入する方法について書いていきたいと思います。

Storybookとは?

StorybookとはUIコンポーネントをカタログのように一覧表示できたり、振る舞いをテストできるオープンソースのツールです。

storybook.js.org

なぜやるか?

新しく始まったプロジェクトをきっかけに、コンポーネントの管理方法やデザイナーとの連携について改めて整理してみようということでStorybookの導入が検討されました。

デザインチーム/フロントエンドチームで事前に用途についても協議してみました。

  • デザインチーム
    • コンポーネントのチェック(どんな種類/どんな挙動か)
    • スタイルガイドの管理
  • フロントエンドチーム
    • コンポーネントのチェック(どんな種類/どんな挙動か)
    • デザインチームへの共有

両チームとも基本的にコンポーネントの管理/共有に使いたい(ボタンやフォーム単位のパーツについて)という意見だったので、ページ全体など大きい単位での表示テストの用途には使わず、まずは小さい単位でのコンポーネントの管理/共有・スタイルガイドとして活用していこうという内容で認識を合わせました。

さっそくStorybookを導入してみる

まずはNuxtのサンプルプロジェクトを作成します。

% yarn create nuxt-app sample-project

作成したプロジェクト内でstorybookを導入していきます。

yarn add -D @storybook/cli
yarn sb init --type vue

yarn storybook

f:id:kinokonotani5656:20200611100741p:plain
storybook initial

storybook/cliは現在のlatest版(5.3.19)を使っています。
無事Storybookが立ち上がりましたが、Nuxtアプリケーションの本体を立ち上げようとしたらエラーが発生してしまいました。

yarn run dev
Type checking in progress...
 ERROR  Failed to compile with 39 errors
* core-js/modules/es6.array.from in ./.nuxt/client.js, ./.nuxt/components/nuxt-link.client.js
 .............
To install them, you can run: npm install --save core-js/modules/es6.array.find core-js/modules/es6.array.from core-js/modules/es6.array.iterator core-js/modules/es6.date.to-string core-js/modules/es6.function.name core-js/modules/es6.object.assign  .............

core-jsでめちゃめちゃ怒られます。 Storybookを導入した時にbabelとcore-jsのバージョンで依存関係の問題が発生してしまうようです。解消するためにここでは明示的にcore-jsの2系を指定してインストールし直しました。

yarn add core-js@2

あとはstoriesファイルと設定を追加していきます。 今回はpropsやdescriptionを作るためのaddonも追加してみました。

yarn add -D @storybook/addon-knobs
yarn add -D storybook-addon-vue-info

addon有効にする設定を追加します。

// .storybook/addons.js
import 'storybook-addon-vue-info/lib/register';
import '@storybook/addon-knobs/register';

configファイルを追加します。

// .storybook/config.js
import { configure, addDecorator } from '@storybook/vue';
import { withKnobs } from "@storybook/addon-knobs";
import { withInfo } from 'storybook-addon-vue-info'

// xxx.stories.jsに対してaddonを反映
addDecorator(withInfo)
addDecorator(withKnobs);

// どのファイルを見るか設定する。今回は../components下のstoriesファイルを対象にする
configure(require.context('../components', true, /\.stories\.(js|ts)$/), module);

storiesファイルを作成。

import { storiesOf } from '@storybook/vue'
import { text, select } from '@storybook/addon-knobs'
// サンプルで作成したコンポーネント
import Button from '@/components/atoms/button/index.vue'

const stories = storiesOf('Buttons', module)

stories.add(
  'button sample story',
  () => {
    return {
      // 対象のコンポーネント設定
      components: { Button },
      props: {
        colorStyle: {
          type: String,
          default: select('colorType', ['green', 'orange'])
        },
        value: { type: String, default: text('default', 'sample') }
      },
    // 描画する内容を設定
      template: `<Button :value=value :colorStyle=colorStyle />`
    }
  },
  { info: true }
)

Buttonコンポーネントの表示を確認できるようになります。

f:id:kinokonotani5656:20200611100837p:plain

GitLab Pagesで公開

毎回環境を立ち上げなくてもいいようにGitLab Pagesで公開するようにしました。 masterにマージされたタイミングでGitLab Pagesを更新するようにしたgitlab-ci.ymlファイルの設定がこちらです。

image: node:latest

cache:
  paths:
  - node_modules/

pages:
  stage: deploy
  tags:
    - sample_runner
  only:
    - master
  before_script:
    - 'yarn install'
  script:
    - 'yarn build-storybook'
    - 'cp -pr storybook-static ./public'
  artifacts:
    paths:
      - public

最後に

今回は記載していませんが、Jestと連携してstoriesファイルのスナップショットテストをすることもできるようです。コンポーネントの管理/共有をするために便利なStorybookですが、更新せずに古くなってしまっては意味がないのでスナップショットテストと連携するなど必ず更新する仕組みをつくっていくことも課題になります。

実運用はまだはじまっていませんが、デザイナーとエンジニアお互いにとって幸せな開発環境にできれば良いなと思います!