けけずんセルフハッキング

忘れそうなことをメモる。

2018年振り返り

はじめに

2018年の振り返りをしてみる。 毎年やるやる言ってやってなかったが、さすがに今年は色々と変化があったので記録として残しておきたいと思ったのがきっかけ。

月毎の振り返り、身につけたスキルなど書いていく。

月毎の振り返り

  • 1月
    • 色々考えて転職を決意する
      • 前職の OGS(沖電グローバルシステムズ) はとても良い環境だったが、前向きな理由で転職することにした
      • 元々Startupな企業に興味あったし、タイミング的にも丁度よいかなと思っていた
    • 前職の上司に転職を伝える
      • かなり驚いていた
      • 社員みんな良い人達ばかりだし、みんな頑張ってたから転職を伝えることに申し訳無さを感じた、すまんな...
      • ひとまず3月末に退職するということで話を進める
  • 2月
    • 転職先の 株式会社Re:Build で必要な技術を身につけるために勉強する
      • PHPとLaravelの勉強してた
      • PHPうんこって聞いてたけど、PHP7系は割と良いという感触があった
    • 正式に退職届を提出する
      • 会社のプリント用紙を使って退職届を作成した
      • 退職届を入れる封筒もプリント用紙で作成したのは内緒
    • 前職で引き継ぎ作業など考慮して4月末に退職することに
      • 転職先で4月からプロジェクトに入る予定だったが、ずらしてもらった
  • 3月
    • 前職で引き継ぎ作業を開始する
      • 担当してきた案件のドキュメント整理
      • 退職手続きも平行して実施
    • 親に転職する旨を伝える
      • 母親は勿体無い勿体無いと引き止めてくる
        • 人によると思うけど母親って大体こういうもんだよね、ブレーキ担当
      • 父親はやりたいようにやればいいと肯定してくれる
        • よく考えると、これまで自分がやりたいと言ったことに対して否定されたことがなかった気がする
      • どっちも思った通りの反応だったので、それはそれで良かった
  • 4月
    • 前職で引き継ぎ作業をしつつ有給休暇を消化する
      • 前職は4月に有給休暇(15日だっけ?)が付与されるので、全部消化しました
      • 週一勤務で引き継ぎ作業を実施、他は転職先のための勉強
    • 4月末に前職のOGSを退職する
      • 2年間で制御チームとインフラチームに所属
        • 1年目は制御チームに所属
          • 某電力会社で使われているシステムの構築を行った
          • Python、仮想環境でのシステム運用、ネットワーク監視などを学んだ
          • 直属の上司が凄く優秀な方だったため、社会人としてもエンジニアとしても非常に勉強になった
        • 2年目はインフラチームに所属
          • 某電力会社や外部企業のインフラ構築・保守を行った
          • 物理・論理ネットワークの構築や運用、セキュリティなどを学んだ
      • 2年間でいろいろ資格を取得
      • 本当に良い職場でした、2年間ありがとうございました
  • 5月
    • 株式会社Re:Build(以下、リビルドと表記する)に入社する
      • 自分と社長を合わせて合計3人のベンチャー企業
      • 人生初のリモートワーク、ワクワクすっぞ
    • リビルド初の開発案件に参加する
      • PHP, Laravelで開発を開始
      • インフラ構築なども担当する
        • ここで前職で学んだことが活きた、感謝感謝
    • ピアノ・ドラム教室に通い始める
      • 以前からピアノ弾きたいと思ってたので知り合いのピアノ教室に通い始める
      • ついでにドラムも教えてもらっている
  • 6月
    • リモートワークに不安を感じる
      • 入社したばかりというのもあり、最初のうちはリモートワークの自由さに何一つ不安を抱えることはなかった
      • 入社して一ヶ月してから、リモートワークを続けていくうちに謎の孤独感を感じ始める
        • 先に入社した同僚もそういった不安に駆られる時期があったらしい
    • 福岡で開催される「PHPカンファレンス福岡2018」にLT枠で登壇する
      • 人前でプレゼンすることに苦手意識があったが、やってみると割と面白かった
      • イベントの他のセッションも非常に勉強になった、テキストベースの勉強もいいけどこういったイベントで勉強することも大事だな
  • 7月
    • リモートワークに慣れる
      • 働き方に慣れてきて、不安感など感じなくなる
      • そういったものを感じる際は同僚に声をかけて一緒に作業をするなど、工夫するようになる
  • 8月
  • 9月
    • リビルドで別案件の開発を開始する
      • PHP, Laravelで開発を開始
      • これまでの期間で得たノウハウもあり、比較的スムーズに進む
      • そのときにフロント(HTML, CSS)のスキルが弱いなと感じた
    • Startup Weekend Okinawa Vol.8」に参加する
      • Startup Weekend Okinawaに二度目の参加、前回のこのイベントが転職のきっかけになった
      • 前回は人が提案したアイディアに便乗して参加していたが、今回は自分がアイディアを提案し、共感してくれた人たちとでチームを組んだ
        • いいメンバーに恵まれた、今でも交流を続けている
      • 3日間という短い期間だが、毎度多くの学びがあった
  • 10月
    • リモートワークを活かして旅行に行く
      • 愛知と岐阜に行ってきた
      • リモートワークだし試しに旅行しながら仕事するかと挑んだが、期限的に厳しい時期だったため平日は部屋に籠もって作業してた
      • コワーキングスペースとか周ってみたかったな、余裕あるときにまた行ってみたい
      • 愛知は味噌カツ、岐阜はタン麺が美味しかった
    • リビルドで自社サービスの開発を開始する
      • 10月頭に実施した開発合宿で考案されたサービスを自社サービスとして進めていくことが決定した
      • 社長が企業やエンジニアにインタビューしてアイディアをブラッシュアップしつつ、傍らで自分と他のメンバーで実装を進めていく
  • 11月
    • バンドを結成する
      • 何を言っているのか分からないだろうが、バンドを結成した
      • メンバーはリビルドの同僚と自分の親友の合計3人
      • たまに集まって練習している
    • Scrum Coaching Retreat Okinawa」に参加する
      • イベントの趣旨を分からず誘われるがままローカルスタッフとして参加した
      • 普段関われないような方々と交流できた
      • レトリートよい、〇〇レトリートとして他にもやってみたい
    • リビルドの自社サービスが「Okinawa STARTUP PROGRAM」に採択される
      • 社長めっちゃ頑張ってた、ありがとうございます
      • 今後も頑張る
  • 12月
    • リビルドで担当している案件でGolangを導入する
      • 以前から勉強はしていたものの、実務で使用したことがなかったGolangを使用して開発を開始した
      • 静的言語楽しい、コンパイルでお叱りを受けてそれを直していく感じ楽しい
    • 宮崎で開催される「Webナイト宮崎 Vol.2」にLT枠で登壇する
      • 自社サービス開発メンバーのお誘いで急遽参加させてもらった
      • 宮崎また行きたい

身につけたスキル

プログラム言語

フレームワーク

  • Laravel5
  • Vue.js
  • Nuxt.js

その他

  • Docker
  • AWSいろいろ

おわりに

2018年は転職をすることで仕事環境が一変するだけでなく、プライベートも充実した年だった。 リビルド初期メンバーとの出会いがなければ、今の自分はいないのだろうなと深く感じている。 素晴らしい環境と、その場所を作ってくれた社長に感謝。

2019年も頑張るぞい。

Nuxt.jsでページ遷移後に動作するくるくる(ローディングバー)をmixin使って実装する

はじめに

Nuxt.jsでページ遷移後のローディング時に動くくるくるをデフォルトではなく、独自のくるくるを使いたい。 また毎回各コンポーネントに独自くるくる起動・終了の定義をするのが面倒くさいのでmixinを使って実装を行う。

実装手順

以下にやることを列挙する。

ここまでやれば独自くるくるが動くはず。

独自ローディング用コンポーネントを用意する

サンプルとして、ここのloading.vueを使用する。 components/loading.vueを以下のように編集する。

<template>
  <div v-if="loading" class="loading-page">
    <p>Loading...</p>
  </div>
</template>

<script>
export default {
  data: () => ({
    loading: false
  }),
  methods: {
    start() {
      this.loading = true
    },
    finish() {
      this.loading = false
    }
  }
}
</script>

<style scoped>
.loading-page {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(255, 255, 255, 0.8);
  text-align: center;
  padding-top: 200px;
  font-size: 30px;
  font-family: sans-serif;
}
</style>

start()finish()は定義必須。

nuxt.conf.jsのloadingに上記コンポーネントを指定する

nuxtで動くデフォルトのくるくるに、先程作成したloading.vueを指定する。 nuxt.conf.jsを以下のように編集する。

export default {
  loading: '~/components/loading.vue'
}

mixin用コンポーネントを用意する

以下のようにcomponents/loadingMixin.jsを作成する。 拡張子を間違えないように注意。

export default {  
  data() {  
    return {  
      loadingTime: 1000  
    }  
  },  
  async mounted() {  
    this.$nextTick(() => {  
      this.$nuxt.$loading.start();  
      setTimeout(() => this.$nuxt.$loading.finish(), this.loadingTime);  
    })  
  }  
}

これによりmixinを使用するコンポーネントがマウントされたタイミングで独自くるくるが描画される。 なおthis.$nuxt.$loading.start()はnuxt.conf.jsで指定した独自くるくるの描画を開始を、this.$nuxt.$loading.finish()は描画の終了を行っている。

ローディングを呼び出したい各コンポーネントでmixinを指定する

以下のようにpages/index.vue, pages/about.vueを作成する。

pages/index.vue

<template>
  <div>
    <p>これはindexです。</p>
    <nuxt-link  to="/about">
      aboutに遷移します。
    </nuxt-link>
  </div>
</template>

<script>
import loadingMixin from '@/components/loadingMixin';

export default {
  mixins: [loadingMixin],
}
</script>

pages/about.vue

<template>
  <div>
    <p>これはaboutページです。</p>
    <nuxt-link  to="/">
      indexに遷移します。
    </nuxt-link>
  </div>
</template>

<script>
import loadingMixin from '@/components/loadingMixin';

export default {
  mixins: [loadingMixin],
}
</script>

動作確認

以下のコマンドを実行し、 http://localhost:3000 にアクセスする。 indexとaboutページをそれぞれ遷移すると、遷移後に独自くるくるが動くことが確認できるはず。

$ npm run dev

おわりに

あとはcomponents/loading.vueを好きなように書き換えるだけで色んなくるくるを再現できる。良いくるくるライフを。

参考

「NuxtMeetUp#5」に参加しました

※会社の技術ブログが未だに復旧していないので、一時的にこちらに掲載します

株式会社リビルドの嘉数です!

10/18(木)に渋谷で開催されたNuxtMeeutup#5に参加してきました、渋谷です。基本的に嘉数は渋谷にいるときは楽天カフェで作業してます。楽天ペイで支払うとカフェ半額だし、電源もあるし素晴らしい。

NuxtMeetUp#5(再度枠増加) - connpass

はい、NuxtMeetup#5について書いていきたいと思います。

NuxtMeetup#5に参加した理由

かんぼ(社長)「自社サービスはSPAでいこう(突然)」

最近から開発を始めた自社サービス、社長の意向でSPA化することになりました。嘉数は普段はバックエンドの開発をしている人間ですが、フロントエンドにも興味があったため良い機会と思いSPA化に賛成しました。

かんぼ(社長)「SPA化する際はNuxt.jsを使おう」

嘉数「Vue.js+VueRouterでよくないですか?」

かんぼ(社長)「とりあえず流行にのっておけ」

なるほど。嘉数は流行に疎いのですが、流行にのるのは大事だなと思いNuxt.jsを導入することにしました。あと触ったことが無いものを触るのって凄く楽しいですよね。

そんなわけでNuxt.jsを導入する前にある程度どういったものか情報収集することと、Nuxt.jsを使って普段から開発を行っている人たちと関わることを目的にNuxtMeetup#5に参加しました。

NuxtMeetup#5について

connpassのNuxtMeetup#5募集ページを見ると、参加枠の人数が160人に達していることが分かります。非常に多い。嘉数もインフラ系のイベントにはよく参加するのですが、そういったイベンドでは多くてもせいぜい30人程度でした。フロントエンド界隈の、今回で言えばNuxt.jsの人気具合が伝わりますね。半信半疑だったけどちゃんと流行ってたんだな...。

LTセッションでは、はじめの挨拶とスポンサーLTを含めて合計8人の方が登壇していました。Nuxtがビルドされた際に出力されるバンドルサイズでかすぎる問題、nodeサーバをクラスタモードにしてマルチスレッドで捌く話、Nuxtのハマりどころ、nuxt-i18nを使って多言語対応したけどSEO対策するとheadタグの中身が消える話、NuxtでJAMStackな開発をする話など、様々な話題がLTセッションで繰り広げられました。以下は本イベント内で使用された、現在アップロードされている分のスライドになります。

おわりに

今回はNuxtMeetup#5に参加するためだけに当日早朝から東京入りし、翌日の朝に沖縄に帰りました。沖縄・東京間は流石に結構な旅費がかかりましたが、本イベントに参加したことはそれ以上の価値があったなと思います。情報収集も出来たし、何よりNuxt友達が出来たことが嬉しかったです。イベントを運営してくれたスタッフの皆様、有意義な時間を本当にありがとうございました!

広告・告知など

弊社(株式会社リビルド)は沖縄県内でLaravel勉強会、JS勉強会など様々なイベントを開催しています。沖縄県内にいる方はもちろん、本土の人も沖縄旅行も兼ねてイベントに参加していただけると嬉しいです。

LaradockをHTTPS化

ファイル編集

laradockの以下のファイルを編集する。

nginx/Dockerfile

FROM nginx:alpine

LABEL maintainer="Mahmoud Zalt <mahmoud@zalt.me>"

ADD nginx.conf /etc/nginx/

# If you're in China, or you need to change sources, will be set CHANGE_SOURCE to true in .env.

ARG CHANGE_SOURCE=false
RUN if [ ${CHANGE_SOURCE} = true ]; then \
    # Change application source from dl-cdn.alpinelinux.org to aliyun source
    sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories \
;fi

RUN apk update \
    && apk upgrade \
    && apk add --no-cache bash \
    && adduser -D -H -u 1000 -s /bin/bash www-data

RUN apk add --no-cache openssl \
    && mkdir /etc/nginx/ssl 2> /dev/null \
    && openssl genrsa -out "/etc/nginx/ssl/localhost.key" 2048 \
    && openssl req -new -key "/etc/nginx/ssl/localhost.key" -out "/etc/nginx/ssl/localhost.csr" -subj "/CN=localhost/O=localhost/C=UK" \
    && openssl x509 -req -days 365 -in "/etc/nginx/ssl/localhost.csr" -signkey "/etc/nginx/ssl/localhost.key" -out "/etc/nginx/ssl/localhost.crt"

ARG PHP_UPSTREAM_CONTAINER=php-fpm
ARG PHP_UPSTREAM_PORT=9000

# Set upstream conf and remove the default conf
RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf.d/upstream.conf \
    && rm /etc/nginx/conf.d/default.conf

CMD ["nginx"]

EXPOSE 80 443

nginx/sites/default.conf

server {

    listen 80 default_server;
    listen 443 ssl default_server;
    listen [::]:80 default_server ipv6only=on;

    server_name localhost;
    root /var/www/public;
    index index.php index.html index.htm;

    ssl_certificate /etc/nginx/ssl/localhost.crt;
    ssl_certificate_key /etc/nginx/ssl/localhost.key;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass php-upstream;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #fixes timeouts
        fastcgi_read_timeout 600;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }
}

ビルド

以下のコマンドでビルド、起動する。

$ docker-compose build nginx
$ docker-compose up -d nginx

Laravel5.5で任意のエラー画面を出すときに注意した方がいいこと

はじめに

Laravel5.5で任意のエラー画面を出したくて奮闘した話。最初は下記の要件を満たしたいだけだった。

  • abort関数でエラーコードに応じた任意の画面を出力する
  • ぬるぽや未定義変数を参照するなど想定外のエラーの際に任意の画面を出力する

これをネットの記事を参考にし、Laravelで例外処理をハンドリングしてるであろうapp/Exceptions/Handler.phprenderメソッドを以下のように編集した。

public function render($request, Exception $exception)
{
+    if ($this->isHttpException($exception)) {
+        if ($exception->getStatusCode() == 400) {
+            return response()->view('errors.400', [], 400);
+        }
+    } else {
+        return response()->view('errors.500', [], 500);
+    }
+
-    return parent::render($request, $exception);
}

とりあえずこれでabort関数で任意のページを表示してくれるし、想定外のエラーが起きた際にも500システムエラーページを表示してくれるようになった。やったぜ!と喜んでいるのもつかの間、問題が発生する。

問題発生!

入力されたデータに対する自動バリデーションが思うように動作しなくなった。なんでだろうと思い編集前のapp/Exceptions/Handler.phprenderメソッドを見直すと、

return parent::render($request, $exception);

こいつが目に入った。中を覗いてみると以下のようになっていた。

public function render($request, Exception $e)
{
    if (method_exists($e, 'render') && $response = $e->render($request)) {
        return Router::toResponse($request, $response);
    } elseif ($e instanceof Responsable) {
        return $e->toResponse($request);
    }

    $e = $this->prepareException($e);

    if ($e instanceof HttpResponseException) {
        return $e->getResponse();
    } elseif ($e instanceof AuthenticationException) {
        return $this->unauthenticated($request, $e);
    } elseif ($e instanceof ValidationException) {
        return $this->convertValidationExceptionToResponse($e, $request);
    }

    return $request->expectsJson()
                    ? $this->prepareJsonResponse($request, $e)
                     : $this->prepareResponse($request, $e);
}

ValidationExceptionの文字が見える。なるほど、parent::renderメソッドでバリデーションとっていたのか。今回はparent::renderメソッドを消していた、道理でバリデートされないわけだ。

無事解決!

app/Exceptions/Handler.phprenderメソッドを再び修正する。

public function render($request, Exception $exception)
{
+    if ($this->isHttpException($exception)) {
+        if ($exception->getStatusCode() == 400) {
+            return response()->view('errors.400', [], 400);
+        }
+    }
+
+    if ($exception instanceof ErrorException) {
+        return response()->view('errors.500', [], 500);
+    }
+
    return parent::render($request, $exception);
}

上記のコードの通り$exceptionHttpExceptionのときは任意のエラーページを表示し、想定していないエラーについてはErrorExceptoinで補足してシステムエラーページを表示する。さらにHttpExceptionErrorException以外の何かしらの例外やエラーについてはparent::renderメソッドで処理をするようにし、自動バリデーションなど適切に処理が行われるようにした。

おわりに

既存のコードに変更を加える前にしっかりと周辺のコードを読み込まないとアカンですね。気をつけよう。

参考