コネヒト開発者ブログ

コネヒト開発者ブログ

Amazon Auroraの良さについてまとめてみた

こんにちは。インフラエンジニアの永井(shnagai)です。

サービスで使っているDBをRDS for MySQLからAuroraへ移行するプロジェクトを進めていて、 色々と知見が溜まってきたので、これまでAWS SAの方に聞いたりwebで調べたことについてざっとまとめてみました。

アーキテクチャ

リーダエンドポイントによる負荷分散と共有ストレージモデルのメリットが大きい

  • リードレプリカアクセスにLB機能がある
    • リーダエンドポイントによって、ヘルスチェック&ラウンドロビンで読み取りアクセスに負荷分散
    • レプリカ0の場合は、writerにアクセスがいく
    • アプリケーション側のエンドポイントとしては、リーダエンドポイントを指すことでr53では出来なかったヘルスチェック機能付き負荷分散可能(パブリックアクセス許可しないとr53からのヘルスチェックは使えない。。) & HA Proxyやライブラリで行っているLB機能をAWSに任せられる
  • RDS for MySQLだと、Multi-AZ構成で無駄になっていたスタンバイインスタンスがリードレプリカとして使える
  • 共有ストレージモデルなので、レプリカの遅延とほぼ無縁(3AZ 6つのストレージに非同期書込)
  • MySQL5.6互換なので移行にあたりアプリケーションの改修は不要(まだ検証中だが今の所何もなさそう)
  • Auroraインスタンスを束ねるクラスタという概念があるので、クラスタ内のノードの状態について管理する必要がない

運用面

ほぼDBA的な仕事が不要になったり、運用の為の細かい作り込みから開放

  • ストレージ、キャッシュ、DBエンジンが分離されているから再起動が早い
    • DBエンジンの再起動のみなので、Aurora再起動は1分以内で
    • 再起動後のあたため(キャッシュ作り)が不要
  • 暗号化もオプション一つで可能
  • SQLによるフェイルオ−バーテスト(カオスエンジニアリング出来る!!)
    • ALTER SYSTEM CRASH [{INSTANCE | DISPATCHER | NODE}]
  • 1分でfail over (リードレプリカありのケース)
  • 監査要件で必要とされがちな、AuditLogを有効にした際のパフォーマンス劣化が少ない
    • RDS for MySQLだと1/3ほどになるという話もあったのでサービスで使うインスタンスには使いづらかった
  • ゼロダウンタイムパッチ(ZDP)
    • ダウンタイムゼロでのパッチ適用
    • セッション切断しないのアプリケーションエラーは起きず、5秒ほどのスループット低下のみ
  • DBクローン機能で、本番相当のテストが簡単に出来る
  • バックトラック機能で瞬時に特定時点へのロールバック
    • オペミスしたら瞬時戻すみたいなケースが出来る(もちろん使わないのがベストですがw)
  • ストレージが自動拡張するので、ディスク容量の管理不要(ディスクフルだ。。。からおさらば)
  • コストも下げれる
    • RDSと比べると2,3割高いが、multiAZ構成をはがせるのでその部分でうまくやればコスト削減見込める
  • モニタリングの強化
    • select単位のレイテンシやスループット取れたりCloudWatchで取れるメトリクスがだいぶ増えてる
    • 拡張モニタリングで1s単位でモニタリング出来る

パフォーマンス面

CPUをMySQLよりがっつり使ってスループットを上げるチューニングをしているみたい

ココらへんは、実際に本番の切替を行ってから詳しく見てみる

  • 独自エンジンなので、パフォーマンスアップの為のチューンが諸々あるらしい
    • 独自Cache, Faster index build, Fast DDL
    • 並列度を上げるためのチューンをかなりしてそう??
  • 数%から数10% Disk/IO 性能が高いらしい
  • MySQLと比較すると、統計情報が変わる可能性がある

全体を通じてだいぶ枯れてきている印象で、更新履歴見てもここ2016,2017年で様々なパッチがあたり問題なく運用出来るレベルになっていそうな印象を受けました。

Amazon Aurora MySQL 1.1 のデータベースエンジンの更新 - Amazon Aurora

来月には、実際のAurora移行プロセスについて書こうと思います。

コネヒトではサービスの信頼性向上をミッションに幅広い領域をカバーしながらエンジニアリングの力でサービスをよりよくしていけるエンジニアを募集しています。 少しでも興味もたれた方は、是非気軽にオフィスに遊びにきていただけるとうれしいです。

www.wantedly.com

Greenkeeperでライブラリのアップデートを自動化する

こんにちは。エンジニアの安達 (@ry0_adachi) です、チョコミントが美味しい季節ですね。今回はpackage.jsonとyarn.lockの更新をいい感じで自動化できないかなーと思ってGreenkeeperの検証をしてみたよ、という話です。

Greenkeeperについて

f:id:dachi023:20180624041959j:plain

Greenkeeperはライブラリのアップデートを自動化してくれるGitHub Appです。greenkeeper-lockfileを使うことでyarn.lockにも対応できるとのことなので使ってみることにしました。

競合サービス

Renovateというサービスがあり、こちらもライブラリのアップデートを自動化するためのGitHub Appです。こちらはyarn.lockにデフォルトで対応しており特に設定等は不要そうなのでyarnをお使いの方はこちらの方がいいかもしれません 😇

Renovateについては一休さんの記事がとても参考になりました。

user-first.ikyu.co.jp

料金体系

https://greenkeeper.io/#pricingを見てみると個人とOrganizationのどちらで利用するのかで料金体系が異なり、個人の場合はprivateリポジトリ1個につき$1.5/monthで、Organizationの場合は$25/monthでprivateが10個まで(11個目からは個別に$1.5/month)となっているようです。publicリポジトリはどちらも無料です。

Greenkeeperを使うための準備

CIの設定

  • https://greenkeeper.io/docs.html#prerequisitesに書いてあるようにまずはCIの設定をしておかないといけないです
  • ちなみに1回目にこれを読まずにCI未設定の状態で先にGitHub Appをインストールしたら何も起きなくなってしまいサポートに問い合わせる事になりました 😢
    • 間違えたとしても、GitHub Appを削除→CIの設定をする→再度GitHub Appをインストールでいけるはず、とサポートからは言われました (今回はそれでもダメでしたが...)

GitHub Appをインストールする

  1. https://greenkeeper.io/docs.html#installationあたりを参考にポチポチとやっていきます
  2. 上記手順を2番まで終わらせると「README.mdにGreenkeeperのバッジ追加」と「package.jsonの更新」を含んだPRが作成されます

Greenkeeperが作成したPRをマージする

PRをマージすると初期設定が完了ですが、初回のPRにもpackage.jsonの更新が含まれるのでただしく動作する事は別途確認した方が良いです。

また下記の例だとwebpackが3.xから4.xになってwebpack-cli (もしくはwebpack-command) 入れないとダメになったり、CircleCIで使ってたDocker imageのNodeのバージョンが古くてバージョンアップしたライブラリのenginesの範囲外になってテストがコケました。それくらいだったので手動でサクッと直しましたが、あまりメンテしてなかったリポジトリとかだと最初のPRで地獄を見そうですね。あと、テストがないと動作確認が大変そうです。

Greenkeeperで作成してみたPRの例

f:id:dachi023:20180719192939p:plain

lockfileも更新する

greenkeeper-lockfile を使いましょうということなのでこれをCIに組み込みます。

TravisCIは3行くらいなんで多分サクッと設定できると思います。CircleCIの場合もちょっと書く量が増えますがやってることは変わらないのでWorkflowsがちゃんと分かっていれば大丈夫かなーと思います。

CircleCIのconfig.ymlの例

所感

結論:更新PRを投げて欲しいだけならGreenkeeper、柔軟な設定が必要そうならRenovate

package.jsonとlockfileの更新PRが飛んできてそれをマージするだけなのでめちゃくちゃ楽だなぁ〜と思ったのと、Renovateと比べてやれることは少ないみたいですが、インストール完了までにやることがCIのconfigに書き足すだけなのでシンプルでいいなと思いました。ですが、lockfileがデフォルトで対応されてないのはやっぱりしんどいので改善して欲しいですね...。Greenkeeperの今後のアップデートに期待しつつ、Renovateの動向も追っていきたいなと思います。

社外のエンジニアさんとクローズドなKotlinコントリビュートもくもく会をしてみた

f:id:tommy_kw:20180712131735p:plain

こんにちは

こんにちは、Androidエンジニアの富田です。先日Cluexのアプリエンジニアtakattataさんと一緒にKotlinコントリビュートもくもく会を行い、PRを出すところまでチャレンジしてみましたので内容の共有とKotlinコントリビュートもくもく会の告知をさせていただきます。

takattataさんと始めたきっかけ

僕がKotlinコントリビュートを続けて1年くらい経つのですが、やっと10個くらいマージされたところです。将来的には50、100個とPRをマージされるくらい貢献していきたいですし、さらに「コントリビュートしたい!」と思っている方のサポートをやってみたいと思いつつも、なかなか一歩踏み出せず悶々としていました。そんな時期にtakattataさんの次のツイートを見かけて、「これはご一緒させてもらう良い機会!」と思い、僕から「一緒にKotlinコントリビュートしてみませんか?」とお誘いしたのがもくもく会のきっかけです。急なお誘いにも関わらず参加していただいたtakattataさんに本当に感謝しております。

もくもく内容

先月コネヒトオフィスにて、平日夜の2日に分けて1on1のハンズオン形式で「環境構築」から「サンプルコードのPRを出す」までトライしました。無事作業が終わり、実際に投げてもらったPRは以下の通りですが、僕の調査不足でどうやら既に同様のPRがあったようです...大変失礼しました!!

github.com

本当にざっくりですが作業内容は以下の通りで、ハマるかなと予想していた環境設定も1時間くらいで無事終わりました。ただ思った以上に時間がかかったのが「どのIssueに取り組むべきか」です。これはお互いにYouTrackのIssueを眺めたり、コードを見ながら「サンプルコード提供のIssue」なら短い時間でもなんとかイケそうと考え取り組みました。最終的には合計4時間くらいで環境構築からPRを投げるところまで出来ました。

  • 環境構築
    • Readmeを見ながら環境を設定する
  • YouTrackのアカウント登録
    • Issueを管理しているYouTrackにアカウントを登録する
  • Kotlin Slackの#kontributorsチャンネル設定
  • サンプルコード提供のPRを出す

環境設定でハマったこととして、テストの緑色の実行マークが表示されなかったことです。初日の環境設定では表示されていたのですが...諦めて以下の通りターミナルからGradle経由でテストを動かしました。

./gradlew :kotlin-stdlib:samples:cleanTest :kotlin-stdlib:samples:test --tests "samples.text.Chars"

f:id:tommy_kw:20180712101142p:plain

少しオープンな場へ

クローズドなもくもく会から正式なイベントとしてKotlinコントリビュートもくもく会を開催します! connehito.connpass.com

参加者が集まれば定期的にKotlinコントリビュートもくもく会をやりたいと思います!今回takattataさんと1on1のハンズオン形式でもくもくしてみて、「事前準備が足りなかったな...」、「もっとちゃんと説明できるようにならないとな...」と反省ばかりでしたが、次のtakattataさんのお言葉で継続的にやる!と決心しました。

もちろんIssueの難易度によって異なりますが、PRを投げること自体は大変ではなく、マージされるまでのハードルが高いと課題に感じております。引き続き何か良いアイデアがないか模索していきます。勉強会につきましては嬉しいことにすでに参加枠が埋まっており、もし参加したい方がいらっしゃれば次回も開催しますので、どうぞよろしくお願いします!

コミュニティサービスにおける機械学習のためのアノテーション ~ Annotation Meetupに登壇しました ~ 【資料公開】

f:id:tatsushim:20180706193609j:plain

こんにちは!

CTOの島田(@tatsushim)です。 昨日「Annotation Meetup」に登壇させていただきました。 cloudai.connpass.com 有料(1000円)の勉強会にも関わらず、アノテーションに関心のある方が約50人も集まる会になり、とても盛り上がりを見せていました!

発表資料

私の発表資料はこちらにアップロードさせていただきました。
内容については、ぜひ以下をご覧いただければと思います。

参加して得た学び

最初に登壇のお声がけをいただいたときは、「アノテーション」というテーマでどういう方が集まるのだろう?と思っていました。
実際に懇親会でお話してみると機械学習を活用している方のみならず、アノテーションを受発注されている方もいらっしゃいました。
弊社はアノテーションをすべて自社で行っているので、普段伺うことのできないお話を聞くことができました。

  • 様々なアルゴリズムが提案されているが、多くの場合ラベル付けデータの精度が、学習器の精度を決める要素の大きな割合を占める
  • アノテーションを外注する際にはアノテーターの方を教育して、発注側と受注側で納品されるデータの精度を確認しながら進める
  • アノテーションの際には緊密な課題管理ができるツールを使用する

といった現場のノウハウを伺うことができ、とても興味深かかったです。

終わりに

発表の中で触れているの例のような分類タスクは研究としても前例が少ないです。
加えて、機械学習による事業インパクトを創れることは本当にやりがいがあることだと思っていますので、引き続き機械学習を用いて非連続な成長を創っていきたいと思います!

Annotation Meetup運営の皆様、会場にお越しいただいた皆様、有難うございました。

以上、島田(@tatsushim)がお送りしました!

【Firebase Analytics】新しくなったBigQuery Export まとめ

こんにちは、サーバーサイドのお仕事してます金城(@o0h_)です。
今更ながら忍空2nd STAGE〜干支忍編〜を読みました!黄純いいキャラ。 ここに至る前の話となる、「忍空 7〜9巻」もKindle出ないですかね。。。

忍空―SECOND STAGE 干支忍編― 12 (ジャンプコミックス)

さて、先日「Firebase AnalyticsのBigQuery Exportで、作成されるスキーマが刷新される」という変更が実施されています。
コネヒトでは大変便利にFirebase Analyticsのrawデータを用いた集計・分析を行っていたので、今回の変更は冷静かつ迅速に対応する必要がある内容でした。(以前書いたこの記事とか。)

今回は、「実際どう変わるの」「何を対応すればいいの」といったポイントをまとめたので、折角なので公開しちゃいたいと思います。

https://cdn.mamari.jp/authorized/amana_5b385c1a-8b34-46c0-a57b-0043ac120002.jpg

お品書き

  1. 変更の背景は?
  2. 実際にどう変わるの?新しいスキーマはどうなるの?
  3. 移行に際してやることは?
続きを読む

0からAndroidチームとしてチームビルディングをやってみた

f:id:tommy_kw:20180326191437p:plain

こんにちは

こんにちは、Androidエンジニアの富田です。コネヒトのAndroid専任エンジニアは僕1人で心細い状況だったのですが、昨年11月にAndroidエンジニアの関根さんにジョインしていただき、晴れてAndroidエンジニア2名体制となりました。そこで今回はAndroidエンジニアが1名から2名になったことでチームとして始動しましたので、チームビルディングについて共有したいと思います。「我々はどこから来たのか」、「我々は何者なのか」、「我々はどこに行くのか」というゴーギャンの3つの問いを参考に、過去、現在、未来とそれぞれ振り返り、未来を創造したいと思います。

過去 〜Androidエンジニア1名体制〜

1人でAndroid版ママリを開発していた時は周囲を巻き込むことなく黙々とIssueに取り組んでいました。アウトプット面に関して言えば、コネヒトは開発ブログを書く文化が浸透していて昨年だけで46本の開発ブログが公開されています。僕もその文化に便乗させてもらってKotlin関連のブログを公開することでコネヒトのAndroidのプレゼンスを少しでも高めようとしました。

tech.connehito.com

しかし、1人でプレゼンスをあげることに限界があり、さらにサービスや事業拡大と共に自分自身が属人化や単一障害点になっていることに気づきチームビルディングについて意識するようになりました。加えて僕は自分ゴト化や周りを巻き込むのが苦手なので、これを機にスモールなチームで主体性を身につけて会社やサービスに対して貢献、または知識を還元したいと思いました。

現在 〜Androidエンジニア2名体制〜

その後嬉しいことに関根さんにジョインしてもらいました。ここからAndroidチームとしてゼロスタートするのですが、まず僕たちが何を目指すのかディスカッションしてみると、「自己完結型のチーム」、「エンジニア自身の成長」、「社外に対してプレゼンスを高める」などの目標、課題がみつかり、具体的に次のように目標を設定してチームビルディングに取り組みました。

プロダクトの品質を高めるチーム

ネイティブアプリの解析系ツールはたくさんありますが、ツールが多すぎてうまく活用できていないと感じた事はありませんか?コネヒトでも同様に Google AnalyticsMixpanelBigQueryFirebaseAdjustなど多くのツールを利用していたため、データの所在がわかりにくいという問題がありました。

先日永井さんの記事でも紹介されていましたが、コネヒトでは非エンジニアでもデータ出しに対する敷居を下げるために「データの民主化」が促進されており、データの一元化やカジュアルにデータ分析できる環境が整っています。ネイティブエンジニアはあまりSQLを触る機会が少なかったため、社内でRedash勉強会を開いて施策に対して僕らでSQLを書き、ダッシュボード化や効果の見える化を推進しました。tech.connehito.com

アンチフラジャイルなチーム

下記のいとしょさんの記事でも言及されていますが、変化を楽しみ、進化を続けるチームになるべく、以下の3点をやり遂げたいと思っています。

  • 職能・職域に囚われない
  • 小さな失敗を繰り返して成長する
  • ルールなしで自走出来るようにする tech.connehito.com

具体的にAndroidチームとして実際に行ったことは以下の通りです。

  • スプリント毎にKPTを用いた振り返り
  • 毎日朝会をすることでチームとしてやることを明確化

コネヒトの開発チームは1スプリント2週間単位の開発体制を導入しています。開発チームとは別にAndroidチームとしてKPTを用いた振り返りを実施し、「Kotlin率80%」、「クライアントチームで時間をとってRedashで施策に対しての見える化」、「リグレッションテストの作業分担」などのトライを行いました。また振り返りでは、「支え合い」、「自走サポート」などを心がけていたため、チームだけでなく、組織としての個人目標についても困ったことがないか共有し合っていました。

エンジニアが成長している

DroidKaigi 2018のアプリのコードが公開された日に自発的にお互いカンファレンスアプリにコントリビュートできました。残念ながら2018年のCfP応募は落選したためコネヒトからは誰もDroidKaigiに登壇できなかったのですが、「来年こそはDroidKaigiで登壇したい!」、「スタッフになりたい!」など自然と新しい目標が生まれました。

github.com

github.com

ママリのAndroidアプリはJavaとKotlinが混在するアプリで半年前までKotlin率が60%だったのですが、現在はKotlin率84%となりました。Kotlin率を上げるためだけにコンバートを行っているわけではなく、例えば仕様を理解するためやリファクタリング時にコンバートしていて、地道にですがKotlin率100%が見えてきました。 f:id:tommy_kw:20180612211105p:plain

社外に対してもプレゼンスをあげる

Connehito Marchéというコネヒト初の社外勉強会を開催しました。白金高輪界隈では、あまり勉強会が開催されいない印象でしたが、多くの方にLT登壇していただき少しプレゼンスをあげることができました。引き続き白金高輪界隈を盛り上げて行きたいと思います。 tech.connehito.com

僕がKotlinにコントリビュートしている関係で、関根さんにもKotlinのコントリビュートにチャレンジしてもらいました。最初のコントリビュートに対して少し敷居が高いと感じていたため、Dev Dayを活用してハンズオンを行いPRまで投げてもらうところまで進めました。Dev Dayとは普段の業務の中で取り組めない課題の解決や業務の改善を通じてコネヒトをより良くする日を設けています。今後の目標はAndroidエンジニア全員がKotlinにコントリビュートしてコントリビュート率を100%にすることです! github.com

未来 〜サービスデザインチームへ〜

目標に対して引き続きトライすることに変わりないのですが、特にサービスデザインを出来るチームを目指したいと考えています。サービスデザインとは、課題に対して一方的な価値の提供ではなく、共創という観点からさまざまな人々を巻き込んでその能力を引き出しながら、これまでにないサービスを作り出す方法です。以下のきよえさんの記事ですが、これがチームビルディングを行う上で良いヒントとなっています。デザイナー、非エンジニアだけでなく、エンジニアもサービスデザインをすることによってより良い関係性を生むと思いますし、クローズドなコミュニティを展開する僕たちエンジニアもプロダクトや組織の良さを発信し続けなければならないです。 note.mu

決意

「過去を振り返り」、「現在を見つめて」、「未来を思い描く」これらをステップごとに振り返ることによって、今後のやるべきことが明確化されました。改めてAndroidチームとして僕たちの存在意義ってなんだろうとディスカッションしてみると、「ママの一歩を支えるため」、「Androidユーザが快適にアプリを利用できる」、「質の高いママ向けアプリを提供するため」などのキーワードがありました。これらを達成するためにサービスデザインを実現できるチームへと変化して行きたいと思います。

サーバーサイドエンジニアがPhpStormでJSを書くために設定したこと

f:id:supermanner:20180612125259p:plain いつもコネヒト開発者ブログを読んでくださっている皆さま、こんにちは。 サーバーサイドを書いている結城(@super_manner)です。
最近は通勤途中に海外ドラマのシリコンバレーを見ることにハマっています。 好きな登場人物はギルフォイルです。過激なワードのリスニング力が上達しましたw

さて、導入の自己紹介やタイトルでも触れましたが、私はコネヒトでは普段サーバーサイドを担当しており、PhpStormを使用してAPIを書いているのですが、ひょんなことから最近はフロントエンドのIssueにもチャレンジすることになりました。
すごく新鮮なので、毎日楽しくコードを書いています(^^)

初めは社内のフロントエンドエンジニアから便利なパッケージを教えてもらえることもあり、JSを書くときのみAtomを使用していたのですが、数ヶ月つづけていると、フロントエンドとバックエンドを書くときでエディタを切り替えるのがやっぱりめんどくさい!!!と感じるようになりました。
そこで、コーディングに使用するツールを今まで使用してきた馴染みのあるPhpStormに寄せてしまうことにしました。

いろいろ強力な機能を持っているPhpStormですが、今回はこれがないとJSを書くときに辛いなぁと感じた基本的な「Flow」と「Prettier」の設定についてご紹介します。
意外とまるっとまとまっている日本語の記事がなかったので、参考になれば幸いです。

参考:コネヒトのフロントエンドについての記事です 👇 tech.connehito.com

Flowの設定

コネヒトでは型チェックにFlowを使用しています。 下記の手順で設定することによって、型が間違っているとFlowのタブが立ち上がり教えてくれます。

  1. Preference -> Language & Frameworks -> JavaScript を開く
  2. JavaScript language versionを Flow に設定 (すると Flow and JSX in ECMAScript6 も読んでくれました)
  3. Flow package or executable の項目にFlowのpathを記入する

f:id:supermanner:20180606191449p:plain

型が変だと、このようなタブが開きます 👇 f:id:supermanner:20180606191523p:plain

prettierの設定

すでに多くの方が導入されているであろうprettierも一緒に設定してしまいます。ファイルの変更をリアルタイムに検知して修正してもらいたいので、File Watchersを使います。JetBrainsのブログにわかりやすくまとまっていたので参考にしました。 今回はeslintの設定を噛ませているのでprettier直実行ではなくeslintでの実行となります。 コネヒトの環境はこちらの記事でご紹介しているので、興味があれば見てみてください! (githubはこちら) tech.connehito.com

  1. Preference -> Tools -> File Watchers を開く
  2. +を押して新規作成し、好きな名前をつける
  3. 整形対象のFileと監視対象のScopeを選択する
    1. 今回はtypeはJavaScriptにしました
    2. Scopeは余計な設定系のJS Fileまで監視しないように設定しておくのがいいかなと思います
  4. Tool to Run on Changeに必要なものを記載していく
    1. Programの項目に, eslintの実行ファイルのpathを記載
    2. Arguments に -c /path/to/.eslintrc --fix $FilePathRelativeToProjectRoot$ を記載
    3. OutPut paths to refreshに $FilePathRelativeToProjectRoot$ を記載
    4. Working directoryに $ProjectFileDir$を記載
  5. お好みでAdvanced Optionsを設定

f:id:supermanner:20180606191735p:plain

こちらもSyntax Errorがあると、タブが開いて教えてくれます👇 f:id:supermanner:20180606191813p:plain

ちなみに、IDE自体の設定なのですがAuto Saveの設定をしていると何回もFile Watcherが走って大変重いので、差支えがなければ外しておいたほうが良いかもしれません。 この辺りはまだまだ未知の設定がありそうなので、もっと早く出来る設定があれば是非共有していただきたいです!

また、本エントリーでは触れていませんが、Extra Toolとして設定して任意のタイミングで実行する方法も公式ブログにありますので見てみてください!

最後に

私はなんとなくずーっとJSに苦手意識を持っていたのですが、普段自分が使っているツールを使いつつ自動でやってくれるところは任せていくことで、 だんだんと苦手意識も薄まりフロントエンドのコーディングが楽しくなってきました(^^)
とはいえ、まだまだ知らないことがたくさんあるので日々のIssueと向き合いながら勉強していきたいと思います! もし同じようなことを思っている方がいて、この記事がちょっとでも踏み出す一歩になれば幸いですmm