RIT Tech Blog

株式会社RITのエンジニアが知見を共有する技術ブログです。

RITのインターンを卒業します

はじめまして.RITでエンジニアのインターンとして働いている石川です. ちょうど参画してから2年目 & 就職でRITとお別れなので,感謝の意を込めて振り返り記事を書かせていただきます.

要約

  • 入る前
    • 自分は知識だけで経験不足の役に立たない人間
    • ITベンチャーでレベルアップしたい
  • 予想通り
    • 大きい裁量
    • メンバーの距離が近い
  • ギャップ
    • 賑やか
    • ギスギスしてない
  • 経験したプロジェクト
    • JWBF:顧客と開発のバランス
    • VOV:ログ
    • その他:いろいろ
  • これから

入る前

RITで働き始める前は,知識だけで経験不足の役に立たない人間でした.

情報系の大学に所属してたり,応用情報技術者の資格を所持してたりと,最低限のITやプログラミングの知識・能力はありました. 一方で,自分で何かちゃんとしたサービスを作ったこともなく,得た知識が業務でどのように役立つのか分かりませんでした.

このままでは社会の役に立てないので自分の経験を積みたいと思い,以前のバイトをやめてITベンチャーのRITに入りました.

予想通りだったこと

裁量が大きい

メンバーが少ないので一人ひとりに大きい裁量が与えられます.(僕がベンチャーを選んだ理由) インターンの身分でもクラウドサービスのかなり重要な権限も付与してもらったりしました. また,企画やミーティングなどでも自分の意見を尊重してもらい,方針を左右したりも. 裁量が大きいと色んなことができて楽しいです.

メンバーの距離が近い

また,メンバー間の距離が近いです. 新年会や忘年会だけでなくBBQしたりしますし,プライベートで遊んだりしています.

人生ゲームの極辛を遊んだのはいい思い出です. 救済システム(不運からプレイヤーを守ってくれる)を認識しておらず,負債者続出. 30万くらい借金抱えた人もいたり.

ギャップ

賑やか

10人近くのメンバーがオフィスにいてわいわいしてます. また,コンサルタントの多くは他の場所にいるのですが,その方々がオフィスに来たときは更に賑やかで楽しいです.

とか思って書いてたら,新型コロナで安全をとってみんなリモートに🙄(2020年2月時点)

ギスギスしてない

スタートアップと聞くと,ありがちなのが距離が近いゆえにギスギスした関係. ドラマだとメンバー間で問題発生してチーム決裂みたいなことがよくあります.

RITでは,メンバー皆がより良いサービスを提供しようと従事していますが,居心地が悪いと感じたことや悪そうな人はいないです. プロジェクトに問題は付き物ですが,発生しても人ではなく仕組みに原因があると考え,問題の発生しない仕組みを議論して構築・改善しているからだと思います.

あと,地味ですが労働環境が整っていることがこれを支えているのかなと思ったり. オフィスは広く,大きいモニターや人間工学に基づいた座り心地の良いイスが配備されてますし,コーヒーメーカーや軽食も置いてあります. さらにスタートアップにありがちなブラックに深夜遅くまで仕事して体を壊すなんてことはないです(多分?).

これまで

二年間で様々なプロジェクトに携わってきました. 紹介するには多すぎるので2つだけ取り上げます.

JWBF

jwbf.gr.jp

一つ目は日本車いすバスケットボール連盟のホームページです.主に,フロントエンドとWebサーバーの開発に携わらせていただきました.

主に用いた技術は次の通りです.

他の記事でも言っている通り,RITではフロントエンドはReactを用いることが多いです.ただ,このプロジェクトではVueにチャレンジしています.書き方などを覚えれば特に問題ありませんでした.ただ,VSCodeのVueのショートカットが一部非対応なため少し煩わしかったです.それ以外ではVSCode最高!!

このプロジェクトではモデルの持つ情報量が大きく,モデル間の依存関係が複雑でした. また,顧客(サイト管理者)視点では一つの画面に関連する項目を表示・編集できた方が嬉しいので,複数のモデルを管理できるようにしていました. この状態管理がハードで, Aの更新画面でBを更新→Bの更新が完了したら→Cを選択してもらい→Aの情報を入力して→Aの更新を完了する みたいな処理がたくさん存在していました.

顧客としては一つの画面に色々な機能があったほうが使いやすいことも多いですが,開発側としては一つひとつがシンプルな方が楽だと実感しました.(そもそもそんなに大変だと予測できてなかった😵)

顧客と開発のバランスは大事.このバランス調整こそSEの力の見せ所だと思うので,次の職場で経験していきたいポイントです.

vov

2つ目は,ビンテージアイテムのWikiプラットフォームのvovです.ユーザは読者と編集者がいて,主に読者側の開発を行いました.また,ログの設計と基盤の構築も行いました.

vov-vintage.com

主に用いた技術は次の通りです.

Webアプリ自体はいつもの構成(Next.jsだけ未経験)で大きな支障はありませんでした.

一方,ログ関連はほぼ未経験で,BigQueryは少し触ったこと有るけど…というレベル.

Analytics,DataPortalの使い方を学ぶところから始め,KGIツリーやログの完成予想図を顧客に見てもらったり,AnalyticsやFluentd,BigQueryによりログを蓄積させDataPortalで可視化したりと いろいろやることがありました.

知らないことばかりで大変でした. しかし,改めて振り返ってみると構築や思考手順などが残っているので,再現性のある貴重な経験だったと思います.

その他

JWBFとVOV以外のプロジェクトでもWebアプリを中心に開発していました. ReactやRailsなどのいつものWeb系のフレームワークはもちろんのこと,AWSのBeanstalkやECS を用いたインフラ構築も経験させていただきました.(おかげさまでAWSのSAAに合格したり) それ以外にも,案件・顧客に合わせて担当領域を変えていたので,それ以外にも全文検索エンジン,CI・CD,などなど,挙げればキリが無く,本当に色んな分野のスキルを身につけることができました.

また,技術以外にも,チーム開発における流れや大切なことを学ぶことができましたし,企画や立案に携わることもできました.

これから

目標としていたITの業務経験を積むことができました. 中でも,一つの技術領域にとらわれず幅広い体験をできたことは本当に感謝しています.

次の職場ではSEとして働きます.部署やプロジェクトは未定ですが,RITでの経験を活かせばどんなプロジェクトでも活躍できると信じてます.特に,調整力に集中して会得しつつ,技術面で力を発揮していきたいと思います.

AWS SSAを取得しました !

こんにちは!
株式会社RITの前田です。

今回はアマゾンウェブサービスのベンダー資格である、AWS 認定ソリューションアーキテクトアソシエイト(以下、SSA)を取得したので、体験記のようなものを書こうと思います。

なぜAWS SSAを取得しようと思ったか

弊社(RIT)では、一人のエンジニアがフロント側(React)からサーバーアプリケーション(Rails)、インフラ(GCPAWS・Azure)までwebアプリケーションの全てを対応できるようになっているので
業務でクラウドを触る機会が多く、一度網羅的に学習しておかなきゃなと思ったことがきっかけでした。
弊社(RIT)は学習するための書籍代や試験代は会社負担なので、比較的資格などの学習サポートが充実していると思います。

勉強方法

本とwebの問題集で勉強しました。

赤本*1
f:id:keimaeda0817:20200207134327j:plain ↑3回読みました

各種サービス(ストレージ、データレイク、コンピューティング)の概要を掴むにはオススメです。

黒本*2 f:id:keimaeda0817:20200207134348j:plain ↑3回読みました
各種サービスの詳細(CPU,メモリなど)をしっかり学びたい人にオススメです

紹介した2冊の本を中心に勉強しました。
この2冊で勉強する場合、赤本をまず初めに読むことをお勧めします。
AWSのサービス概要についてざっくりと学ぶことができるので、
まず赤本を読み、
その後に黒本を読むと、
AWSのサービスについて全体的なイメージから、個々のサービスの一つ一つの違いが理解できるようになるはずです。

後は、web問題集です。

aws.koiwaclub.com

3ヶ月3000円くらいと、割といいお値段はしますが、
問題数が多く、実際に出てくる問題と近いので、
この問題集で落としたところを、本で重点的に勉強すると効率よく勉強できます。

また、パブリックサブネットやプライベートサブネットの構築など、
実務で触れたところも多く出題されたので、やはり実際にAWSでサーバーなどを構築した方が理解しやすいです。

試験を受けました

平日に業務の合間を縫って試験を受けに行きました。
試験時間は130分、会場にあるパソコンにSSA試験用のアプリケーションがインストールしてあるので、画面を見ながら出題された問題を答えていくといった方法でした。
試験といえば、センター試験のようなみんなでせーので紙に回答を書いていくようなイメージがあったのですが、それとはだいぶ違うので、ギャップで驚きました。

問題は65問あり、しっかり学習していけば、試験時間はだいぶ余ると思います。
僕は70分以上余りました。

試験問題も上で紹介したWEB問題集と比べたら簡単に感じました。
最後の問題を解くと、回答を終了するというボタンが出てきたのでそれを押したら試験終了です。
ボタンを押したら、「おめでとうございます。 試験に合格しました」のような画面が出てきたので、「あっ、合格したんだな」と思いました。
当時は、すごいあっさりと表示するので、本当に合格したんだろうかと思いながら会社に帰ったことを覚えています笑

数日後、AWSのアカウントにSSAの資格を取得したことが反映されていました。
自分が何点取ったのか見ることができます。
合格ラインが720点で、僕の点数が740点くらい結構ギリギリでした。
90%くらいは取った気でいたので、冷や汗をかきました笑

最後に

株式会社RITでは、エンジニア、デザイナーを募集中です。

  • 新しい技術に触れたい人
  • フロントからサーバー、インフラなどフルスタックに開発したい人
  • 新規事業が好きな人

オススメです。

学習サポートとして、書籍代のサポートや資格の試験代のサポートも行っています。

rit-inc.co.jp

*1:AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト

*2:徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書

セマンティックHTMLでセクショニングをする

f:id:sk0515:20191227182921p:plain

はじめに

こんにちは!デザイナーの金森です。

仕事納めですね。2019年いろいろありましたね、お疲れさまでした! RITではデザイナーも企画のアイディエーションから入り、開発まで幅広く携わっています。 今回はその中でも開発の「セマンティックHTML」のお話をしようかと思います。

セマンティックHTMLとは?

セマンティックとは、一般的には「意味」や「意味論」に関することを指す語である。IT用語としては、コンピュータに文書や情報の持つ意味を正確に解釈させ、文書の関連付けや情報収集などの処理を自動的に行わせる技術について用られる語である。セマンティックとは何?Weblio辞書

????ちょっとわかりにくいですね 簡単に説明すると、各部品に対応する意味のあるHTML要素を使いましょうという考え方です。

そうすることによって

  • マシンリーダブルなコードになり、SEOに強くなる

  • 人間にとっても読みやすいコードになる(延々とdivを見比べる必要がなくなる)

  • アクセシビリティが向上し、障がいをお持ちのかたでも快適にサイトやサービスが使えるようになる

などのメリットがあります!

セマンティックHTMLの例

例えば、最上位レベルの見出し要素をコーディングする際に、 <h1>これが最上位レベルの見出し!</h1> と書きますよね? f:id:sk0515:20191227175042p:plain

このように記述することで、検索エンジンがその内容をSEOに影響する重要なキーワードと見なしたり、ブラウザの読み上げ機能などを使用できるようになります。

一方で、正直どの要素でも上記のような最上位レベルの見出しのようなデザインに見せることができます。 <div>これが最上位レベルの見出し?</div> f:id:sk0515:20191227175324p:plain これは一見、最上位レベルの見出しのように見えますが、h1のようにセマンティックな意義がないのでSEOやブラウザの読み上げなどのメリットを受けることが出来ません。

見かけ上は正しいように見えていて書けているけど、SEOアクセシビリティの観点からは良くないというのがHTMLの難しいところですね....! 超基本なことですが、わたしも意図して書かないと良くないコードを書いてしまったりするので常日頃から注意する必要があります。。。

セクショニング・コンテンツ

セマンティック要素はめちゃめちゃある(おおよそ100ほどある)ので、今回はセクショニング・コンテンツだけ取り出して解説します。

セクショニング・コンテンツとは、文章の区分や節などの、区切りを表すコンテンツで以下のものを指します。 順を追って説明していきます。

  • <article>
  • <section>
  • <nav>
  • <aside>

<article>について

HTML の article 要素は文書、ページ、アプリケーション、サイトなどの中で自己完結しており、 (集合したものの中で) 個別に配信や再利用を行うことを意図した構成物を表します。例えば、フォーラムの投稿、雑誌や新聞の記事、ブログの記事などが含まれます。MDN Web Docs: 記事コンテンツ要素

  • 注意点
    • articleの内容が単独で切り出しても、独立して意味を持っていること
    • 子要素として見出し要素が必要(h1〜h6のどれか)
    • 子要素としてsectionタグが少なくとも1つ必要
    • articleのなかで、articleを子要素として持つことも可能
<article>
    <h1>RITについて</h1>
    <p>千代田区にあるコンサルティングとインキュベーションの会社です。</p>
    <section>
        <h2>やってること</h2>
        <p>テキストテキスト</p>
    </section>
</article>

<section>について

HTML の section 要素は、 HTML 文書の中で単独のセクション (区間) を表します。セクションを表現するより意味的に具体的な要素がない場合に使用します。必ずではありませんが、通常はセクションには見出しがあります。MDN Web Docs: 汎用セクション要素

  • 注意点
    • 子要素として見出し要素が必要(h1〜h6のどれか)
    • 単独で切り出しても、独立して意味を持っているものには使用してはならない
      • その場合はarticleを使用すること
    • 文書のアウトライン上のみで使用すること
      • スタイル付けのみが目的なのであれば、divを使用すること
<section>
    <h1>ABOUT</h1>
    <p>この記事はセマンティックhtmlの説明をしています。</p>
</section>

<nav>について

HTML の nav 要素は、現在の文書内の他の部分や他の文書へのナビゲーションリンクを提供するためのセクションを表します。ナビゲーションセクションの一般的な例としてメニュー、目次、索引などがあります。MDN Web Docs: ナビゲーションセクション要素

  • 注意点
    • すべてのリンクに対してnavを使用する必要はなく、ページ内でも重要な部分にのみ使用すること
    • 上述のようにヘッダーやサイドバーなどnav要素は複数使用してもOK!

<aside>について

HTML の aside 要素は、文書のメインコンテンツと間接的な関係しか持っていない文書の部分を表現します。サイドバーやコールアウトボックスなどを表現するためによく使われます。MDN Web Docs: 余談要素

  • 注意点
    • 文章中の括弧書きについては、文章の主要な流れに属するものであるといえますので、これをタグ付けするためにaside要素を使用することはできません
      • 注意書きや、注釈などに用いるための要素です
<p>こんにちは、RITでデザイナーをしている金森です。</p>

<aside>
    <p>余談ですが、好きなことは音楽を聞くことです。</p>
</aside>

<p>これからセマンティックhtmlについて説明します。</p>

まとめ

今回ご紹介したものはHTML構造のアウトラインをつくる上で重要になるものばかりです。 全部divでいいんじゃない???って気持ちにもなったりしますが、ユーザーを一番に考えて良いコードを書くように気をつけましょう。 長くなりましたがここまで読んでくれた方ありがとうございます!良いお年を〜!

Headless CMSのStrapiをECSで運用してみる(後半)

rit-inc.hatenablog.com

↑の続きです

ECRにリポジトリ作る

とりあえずECRにリポジトリを作りましょう

f:id:rit-inc:20191216132313p:plain

f:id:rit-inc:20191216132447p:plain

URIを控えておきましょう

ビルド

ECRにpushするDocker imageをbuildします

PS C:\Users\tetsu\dev\new_blog> docker build -t <↑で控えておいたURI>:latest .
Sending build context to Docker daemon  527.4kB
Step 1/7 : FROM node:12
 ---> 11e92fc50c4a
Step 2/7 : COPY . /strapi
 ---> Using cache
 ---> d12f81986c35
Step 3/7 : WORKDIR /strapi
 ---> Using cache
 ---> 55776038dbb7
Step 4/7 : RUN yarn
 ---> Using cache
 ---> f4e982ccbbc1
Step 5/7 : RUN yarn build
 ---> Using cache
 ---> e986f88a755d
Step 6/7 : EXPOSE 8000
 ---> Using cache
 ---> bc4357547272
Step 7/7 : CMD ["yarn", "start"]
 ---> Using cache
 ---> 3e5b72ab37a0
Successfully built 3e5b72ab37a0
Successfully tagged <↑で控えておいたURI>:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

ECRにpush

ECRへのログインに関しては省略します

PS C:\Users\tetsu\dev\new_blog> docker push <↑で控えておいたURI>:latest
The push refers to repository [<↑で控えておいたURI>]
ddcc6d87877d: Pushed
e16bf0fde55b: Pushed
9b567c0e90e9: Pushed
16bf97960ee7: Pushed
190990e6fae4: Pushed
e44afd48b6d5: Pushed
799e7111d6d4: Pushed
a72a7e555fe1: Pushed
b8f8aeff56a8: Pushed
687890749166: Pushed
2f77733e9824: Pushed
97041f29baff: Pushed
latest: digest: sha256:9daa204795d9930d14f189041a05f8a355623b4684048fef7ff95db827b79f7d size: 2850

f:id:rit-inc:20191216133700p:plain

ちゃんとpushされてる

ECSでタスク作成

FARGATEで作ろう

f:id:rit-inc:20191216133835p:plain

f:id:rit-inc:20191216133957p:plain

f:id:rit-inc:20191216134717p:plain

f:id:rit-inc:20191216134746p:plain

f:id:rit-inc:20191216134805p:plain

設定はこんな感じ

f:id:rit-inc:20191216134849p:plain

できた

クラスター作成

fargateで

f:id:rit-inc:20191216215128p:plain

f:id:rit-inc:20191216215301p:plain

f:id:rit-inc:20191216215443p:plain

できた

タスク実行

f:id:rit-inc:20191216222500p:plain

アラートが出るのでswitch to launch typeでfargateに

VPCはデフォルトで、サブネットは適当に付けちゃいます

セキュリティグループはtcpの1337ポートを開けときましょう

パブリックIPの自動割当はとりあえずENABLED

f:id:rit-inc:20191216222554p:plain

f:id:rit-inc:20191216222703p:plain

f:id:rit-inc:20191216222821p:plain

起動しました

f:id:rit-inc:20191216222931p:plain

pendingからrunningに変わるまで待つ

f:id:rit-inc:20191216223044p:plain

runningになったのでpublic ipにアクセスしてみましょう

f:id:rit-inc:20191216223142p:plain

起動しています

これだと失敗っぽく見えちゃうので管理画面にもアクセスしてみる

f:id:rit-inc:20191216223226p:plain

うまくいってる

まとめと課題

  • 簡単にECSでstrapiのコンテナを実行することができた
  • DBだとかの設定には環境変数の変更が必要(タスクの定義で変えられる)
  • CI/CDにはもうひと工夫必要(commit hashとってきてタスク定義を更新するとか)

長々とECSについて書きましたが、最近はEKSやGKEなどのk8s活用にも力を入れているので、そのうちk8sでも構築してみたいですね

RITでは、様々な技術を活用してクライアントや自社サービスを作り上げることに興味のあるエンジニアを募集しています!

rit-inc.co.jp

iPadで開発業務を効率化

初めまして、RITのエンジニアの前田です。 僕は普段MacBookPro(以下MBP)一台で仕事をしているのですが、サブ機としてiPadを導入したところ意外と役に立ったので、共有したいと思います。

そもそもなぜサブ機としてiPadの導入をしたかというと、 僕はエンジニアなので開発をメインの業務としているのですが、 MBP一台で開発・連絡・タスク管理・メモなど全てを行うことに限界を感じたからです。 こんな感じ↓

画面がグチャグチャ・・・イライラ(`‐●_‐´怒)

そこでサブ機としてiPadを導入して、それにタスク管理とメモは集約させようと考えたのです。 結論から報告すると、かなり良いです。

タスク管理をiPadでするようになりました。

個人的にタスク管理にはTrelloを活用していて、今まではMBPで開いていたのですが、当然開発をしているとその他のたくさんの画面のうちの一つとして埋もれてしまいます。

タスクも一応はTrelloで管理していたのですが、自分のタスクは頭の中だけで管理していたも同然でした。(いつまでにこれをやる。。。など)

頭の中だけでタスクの管理をしていると、開発中も自分の抱えている別タスクがちらついてしまい、開発効率が20%くらい落ちているような気がしていました。

しかし、iPadを導入しタスク管理をそちらに集約するようにしたため、

頭の中でタスクを管理していた分の領域を開発に向けることができ、MBPもタスク管理で開いていた画面が消え、開発に集中して取り組めるようになりました。

また、メモもiPadでとるようになりました。

今までは、紙ベースの簡易的なメモとMBPの文字ベースのメモの二つでメモを取っていました。メモという一つのことをするために、2つの媒体を使ってしまっていて自分の中で管理することができず、とりあえずメモをとるだけになってしまっていました。

iPadでメモを取るようになってから、手書き、文字ベース両方同じ端末で取ることができる上に、開発用のMBPからメモをとる画面を消すことができてだいぶスッキリしました!

f:id:keimaeda0817:20191210183744j:plain

f:id:keimaeda0817:20191210183810j:plain

iPadを実戦投入してみたまとめ

before

  • MBPでタスク管理とか連絡とかメモとか開発全部やるの辛い

after

  • MBPは開発に集中!
  • iPadでメモを一元化、
  • タスクは頭の中で管理するのではなく常にiPadで目の前に出しておく

以上が、iPadを実戦投入してみた感想です。

今後はメモの質を上げていくために経費でApple pencilやiPad用のキーボードの導入も検討しています。

ここまでお読みいただきありがとうございました。

Headless CMSのStrapiをECSで運用してみる(前半)

WordPressのスケーリングとか考えるの辛いしフロントは自由に作りたいですよね?

今回はHeadless CMSのStrapiをECSで運用した話(の前半、ローカルのDockerで動かすまで)をしたいと思います。

環境

  • Windows 10 Pro
  • Node.js 12.13.0
  • Yarn 1.19.1
  • Docker 19.03.4
  • Strapi 3.0.0-beta.17.2
    • 最新版だとstrapi buildコマンドが動かなかったのでちょっと前のバージョン使ってます

StrapiのProjectを作成する

strapi.io

公式のドキュメントに従って進めてみましょう。 Project生成用のコマンドが用意されてるのでyarnかnpxで実行します(今回はyarn使いました)

PS C:\Users\tetsu\dev> yarn create strapi-app new_blog
yarn create v1.19.1
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...

success Installed "create-strapi-app@3.0.0-beta.17.5" with binaries:
      - create-strapi-app
'C:\Program' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
error Command failed.
Exit code: 1
Command: C:\Program Files (x86)\Nodist\bin\bin\create-strapi-app
Arguments: new_blog
Directory: C:\Users\tetsu\dev
Output:

info Visit https://yarnpkg.com/en/docs/cli/create for documentation about this command.

うまくいかない… npxで再チャレンジ

PS C:\Users\tetsu\dev> npx create-strapi-app new_blog
npx: installed 84 in 12.995s
Creating a new Strapi application at C:\Users\tetsu\dev\new_blog.

? Choose your installation type (Use arrow keys)
? Choose your installation type Quickstart (recommended)
Creating a quickstart project.
Creating files.
Dependencies installed successfully.

Your application was created at C:\Users\tetsu\dev\new_blog.

Available commands in your project:

  yarn develop
  Start Strapi in watch mode.

  yarn start
  Start Strapi without watch mode.

  yarn build
  Build Strapi admin panel.

  yarn strapi
  Display all available commands.

You can start by doing:

  cd C:\Users\tetsu\dev\new_blog
  yarn develop


> new_blog@0.1.0 build C:\Users\tetsu\dev\new_blog
> strapi build "--no-optimization"

Building your admin UI with development configuration ...

√ Webpack
  Compiled successfully in 12.32s

Running your Strapi application.

> new_blog@0.1.0 develop C:\Users\tetsu\dev\new_blog
> strapi develop

[2019-11-15T09:28:19.454Z] info File created: C:\Users\tetsu\dev\new_blog\extensions\users-permissions\config\jwt.json

 Project information

┌────────────────────┬──────────────────────────────────────────────────┐
│ Time               │ Fri Nov 15 2019 18:28:21 GMT+0900 (GMT+09:00)    │
│ Launched in        │ 6508 ms                                          │
│ Environment        │ development                                      │
│ Process PID        │ 26676                                            │
│ Version            │ 3.0.0-beta.17.5 (node v12.13.0)                  │
└────────────────────┴──────────────────────────────────────────────────┘

 Actions available

One more thing...
Create your first administrator 💻 by going to the administration panel at:

┌─────────────────────────────┐
│ http://localhost:1337/admin │
└─────────────────────────────┘

[2019-11-15T09:28:21.602Z] debug HEAD index.html (10 ms) 200
[2019-11-15T09:28:21.604Z] info ⏳ Opening the admin panel...
[2019-11-15T09:28:21.763Z] debug GET index.html (3 ms) 200
[2019-11-15T09:28:21.780Z] debug GET runtime~main.c1955456.js (2 ms) 200
[2019-11-15T09:28:21.781Z] debug GET main.9cb7efe0.chunk.js (2 ms) 200
[2019-11-15T09:28:22.114Z] debug GET /favicon.ico (4 ms) 200
[2019-11-15T09:28:22.116Z] debug GET /users-permissions/init (11 ms) 200
[2019-11-15T09:28:22.121Z] debug GET /admin/init (2 ms) 200
[2019-11-15T09:28:22.164Z] debug GET 6301a48360d263198461152504dcd42b.svg (2 ms) 200
[2019-11-15T09:28:22.194Z] debug GET 2ff0049a00e47b56bffc059daf9be78b.png (2 ms) 200
[2019-11-15T09:28:22.204Z] debug GET bd03a2cc277bbbc338d464e679fe9942.woff2 (6 ms) 200
[2019-11-15T09:28:22.204Z] debug GET cccb897485813c7c256901dbca54ecf2.woff2 (5 ms) 200
[2019-11-15T09:28:22.205Z] debug GET 8b4f872c5de19974857328d06d3fe48f.woff2 (5 ms) 200
[2019-11-15T09:28:22.205Z] debug GET af7ae505a9eed503f8b8e6982036873e.woff2 (4 ms) 200
[2019-11-15T09:28:22.206Z] debug GET 33d5f0d956f3fc30bc51f81047a2c47d.woff2 (4 ms) 200
[2019-11-15T09:28:22.210Z] debug GET 4c4e7d0d5ebd40343f6e1281f0bd9438.ico (3 ms) 200

strapiが起動して管理者の登録画面が開くはずなので適当に登録しましょう (1337番portが別のプロセスですでに使われてて一度失敗してます)

f:id:rit-inc:20191115182946p:plain

登録が完了したらダッシュボードに遷移します

f:id:rit-inc:20191115183220p:plain

Dockerで動かす

一旦この状態をDockerで動かせるようにしましょう 公式がDocker Imageを提供してますが今回は手動で構築してみます

github.com

yarnしてbuildしてstartするだけのやつ

Dockerfile
FROM node:12

COPY . /strapi
WORKDIR /strapi

RUN yarn
RUN yarn build

EXPOSE 1337

CMD ["yarn", "start"]

ローカルで生成されたファイルと衝突しちゃうので.dockerignoreも作成しておきましょう

node_modules
build
.cache
.tmp
public

buildして

PS C:\Users\tetsu\dev\new_blog> docker build . -t new_blog
Sending build context to Docker daemon  527.4kB
Step 1/7 : FROM node:12
 ---> 11e92fc50c4a
Step 2/7 : COPY . /strapi
 ---> d12f81986c35
Step 3/7 : WORKDIR /strapi
 ---> Running in 41a2b9cb2e88
Removing intermediate container 41a2b9cb2e88
 ---> 55776038dbb7
Step 4/7 : RUN yarn
 ---> Running in 89413fd02861
yarn install v1.19.1
[1/5] Validating package.json...
[2/5] Resolving packages...
[3/5] Fetching packages...
info fsevents@1.2.9: The platform "linux" is incompatible with this module.
info "fsevents@1.2.9" is an optional dependency and failed compatibility check. Excluding it from installation.
info fsevents@2.1.2: The platform "linux" is incompatible with this module.
info "fsevents@2.1.2" is an optional dependency and failed compatibility check. Excluding it from installation.
[4/5] Linking dependencies...
warning "strapi-admin > bootstrap@4.3.1" has unmet peer dependency "jquery@1.9.1 - 3".
warning "strapi-admin > bootstrap@4.3.1" has unmet peer dependency "popper.js@^1.14.7".
warning "strapi-admin > @buffetjs/styles > react-dates@21.5.0" has unmet peer dependency "react-with-direction@^1.3.1".
warning "strapi-plugin-users-permissions > grant-koa@4.6.4" has unmet peer dependency "koa@>=0.x.x".
warning "strapi-hook-bookshelf > bookshelf@0.15.1" has incorrect peer dependency "knex@>=0.13.0 <0.18.0".
[5/5] Building fresh packages...
Done in 53.53s.
Removing intermediate container 89413fd02861
 ---> f4e982ccbbc1
Step 5/7 : RUN yarn build
 ---> Running in 92f0d4414e4b
yarn run v1.19.1
$ strapi build
Building your admin UI with development configuration ...
ℹ Compiling Webpack
✔ Webpack: Compiled successfully in 24.15s
Done in 25.48s.
Removing intermediate container 92f0d4414e4b
 ---> e986f88a755d
Step 6/7 : EXPOSE 8000
 ---> Running in e8c7cc8fd917
Removing intermediate container e8c7cc8fd917
 ---> bc4357547272
Step 7/7 : CMD ["yarn", "start"]
 ---> Running in da37576c9adf
Removing intermediate container da37576c9adf
 ---> 3e5b72ab37a0
Successfully built 3e5b72ab37a0
Successfully tagged new_blog:latest
SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories.

runしてみる

PS C:\Users\tetsu\dev\new_blog> docker run -p 1337:1337 new_blog
yarn run v1.19.1
$ strapi start

 Project information

┌────────────────────┬──────────────────────────────────────────────────┐
│ Time               │ Fri Nov 15 2019 10:20:05 GMT+0000 (Coordinated … │
│ Launched in        │ 1795 ms                                          │
│ Environment        │ development                                      │
│ Process PID        │ 28                                               │
│ Version            │ 3.0.0-beta.17.5 (node v12.13.0)                  │
└────────────────────┴──────────────────────────────────────────────────┘

 Actions available

Welcome back!
To manage your project 🚀, go to the administration panel at:
http://localhost:1337/admin

To access the server ⚡️, go to:
http://localhost:1337

localhost:1337にアクセスしてみましょう

f:id:rit-inc:20191115192124p:plain

ローカルで実行したときと同じように登録画面が出るはず

ECSで動かす

ちょっと長くなってきたので今回はここまで 次回はECRにpushしてECSで動かすとこまでやります!

React Hooks使ってリファクタしてみた話

CTOの福田です

React 16.8 リリースされましたね

新機能のReact Hooksを使って自社サービスのコードをリファクタしてみたので、全体的な使用感とかハマったポイントを挙げていこうと思います。

前提

  • Reduxは使ってません
  • statefulなコンポーネントを多用してます
  • React + React RouterのSPA
  • TypeScript

ざっくり

  • 〇 Class ComponentがFunction Componentにできてネストが一段減って行数も微妙に削減されてうれしい
  • useState使うとsetState({hoge: 'fuga'})setHoge('fuga')みたいにできてうれしい
  • useEffectの第二引数が直感的じゃない?

詳しく

Class ComponentがFunction Componentにできる & setStateがシンプルに

何かすごいメリットがあるかって言われると微妙なんですが、単純にネストと行数が削減されるのでよいとおもいます

単純なカウンターの例を書いてみると

class HelloComponent extends React.Component<{}, {count: number}> {
    state = {
        count: 0;
    };

    render() {
        return (
            <button onClick={() => this.setState({count: this.state.count + 1})}>{this.state.count}</button>
        );
    }
}

function HelloComponent() {
    const [ count, setCount ] = useState(0);
    return (
        <button onClick={() => setCount(count + 1)}>{count}</button>
    );
}

になります

useEffectの第二引数

componentDidMountajaxしたりcomponentDidUpdateでrefからdomを操作したい場合はuseEffectの第一引数にコールバック関数渡してその中で処理するんですが、asyncなコールバックが渡せなかったり何も考えずにasyncな関数呼び出してその中でsetStateしてると無限ループしちゃうのでちゃんとドキュメント読みましょう

メッセージ一覧を取得して表示する画面で最初書いてたコード(サンプル用に改変済み

import React, { useState, useEffect } from 'react';
import { Message } from '../entities';
import { MessageRepository } from '../repositories';

export default function Messenger() {
    const [ messages, setMessages ] = useState(new Array<Message>());

    const fetchMessages = async () => {
        setMessages(await MessageRepository.getAll());
    };

    useEffect(() => {
        fetchMessages();
    });

    return (
        <ul>
            {messages.map(m => <li key={m.id}>{m.text}</li>)}
        </ul>
    );
}

useEffectはstateやpropsが変更される度に呼び出されるので、この例ではsetMessagesを呼び出すたびにfetchMessagesが呼び出されて無限ループしてしまいますが、 useEffectの第二引数を使うことによって特定の値が変更された場合のみコールバックを実行するように制御できます

なので、ここに空の配列を渡してやることで初回だけ実行されるコールバックが実現できます

useEffect(() => {
    fetchMessages();
}, []);

これで初回だけ実行されるので、componentDidMount相当になります

最後に

ハマりポイント何個か書こうと思ったんですがほとんどハマらなかったので書くことがありませんでした

現状複雑な状態や副作用を持ってるコンポーネントだと大幅な改修が必要になっちゃうんですが基本的にコード量は減るので、新しいコンポーネント書くときには積極的に使うといいんじゃないでしょうか

RITでは新規事業に携わりたい方を様々な職種で募集しているので、ご興味ある方はぜひオフィスに遊びに来てください!

https://rit-inc.co.jp