Studyplus Engineering Blog

スタディプラスの開発者が発信するブログ

散らかったStorybookを整理する

こんにちは。ForSchool事業部の石上(id:shgam)です。今回はStorybookの話です。

7/17にリニューアルしたStudyplus for Schoolでしたが、このとき導入したStorybookを活用できていませんでした。そもそも整備が足りてなかったので、1日もらってStorybookを整理しました。

社内esaとの重複もありますが改めてチームメンバーへの共有も兼ねて、このブログ記事を書いています。

f:id:shgam:20191015144104p:plain
Studyplus for School の Storybook

背景

コンポーネントカタログとして導入してあるStorybookでしたが、リリースに向けて忙しくなるうちに整理が後回しになり、ちゃんと活用できない状態になってしまっていました。

作業の話を始める前に、なぜコンポーネントカタログが必要か、そしてどんな問題があったかを整理しておきます。

そもそもなぜStorybookが必要なのか

  • Storybookのようなものがないと、画面を実装する際使えるパーツを探すのが難しく暗黙知に頼るしかなくなります。整理されたStorybookは、画面実装の助けになると思います。
  • Wikiみたいなところにテキストドキュメントで整理しようとすると、実装との乖離が発生しやすく整理するのは難しいです。Storybookなら実装したものをそのまま置く形になるので、現実のコンポーネントが確認できます。

問題と原因

以下のような問題がありました。

  • Storybookに追加されているけど使い回せないコンポーネントがある
    • 原因:開発初期のコンポーネント分割のスキル不足(Atomic Designの理解が浅いままやってしまっていた)
  • Storybookに追加されてないコンポーネントがある問題
    • 原因:いちいち追加するのが面倒
  • Storybookの認識が曖昧(何に使うものなのか、今どうなってるのか)
    • 原因:ちゃんと整理されておらず、活用方法も特に共有していない

これらを解決するのをゴールに、修正をはじめました。

やったこと

Storybookに追加されているけど使い回せないコンポーネントがある

使い回せないコンポーネントがいくつかStorybookに存在してしまっていました。

本来なら適切にまとめる(たとえば無駄な分割がされたコンポーネントを親のコンポーネントに含める)ことが必要ですが、今回はStorybookの整理なので一旦Storybookから削除することにしました。

Storybookに追加されてないコンポーネントがある問題

いちいち追加するのが面倒だというのが明らかでした。そこで、コンポーネントをつくるときに必ずstoryが追加されるよう、コンポーネント生成コマンドを用意することにしました。

ただそれ以前に、各ストーリーがstories/index.stories.tsxにべた書きされていてファイルが分割できていませんでした。

// .storybook/config.ts
function loadStories() { require('../stories/index.stories.tsx'); }
configure(loadStories, module);

// stories/index.stories.tsx
storiesOf('atoms', module)
  .add('Hoge', () => <Hoge />)
  .add('Fuga', () => <Fuga />)
// これが延々と続く

これでは、コンポーネント生成のスクリプトからストーリーを追加するときに面倒です。

以下のように修正しました。

// .storybook/config.ts
import { configure } from '@storybook/react';
import "../src/styles/global.scss";

const loaderFn = () => {
const req = require.context('../stories', true, /\.tsx$/);
  req.keys().forEach(fname => req(fname));
};

configure(loaderFn, module);

// atoms/Tag.ts
 storiesOf('atoms', module)
  .add('Tag', () => {
    return (
      <Tag tag={{ id: "hogehoge", name: "タグ" }} />
    )
  })

stories以下はこうなりました。

$ tree stories/
stories/
├── atoms
│   ├── Card.tsx
│   ├── DoughnutChart.tsx
│   │_____ ...
└── molecules
    ├── EllipsisDropdown.tsx
    ├── SortLabel.tsx
    ├── ...

これなら、コンポーネントを作るときにストーリーファイルを生成するのも簡単です。atoms/Hogeを作るなら、stories下にも同じ名前で雛形ファイルを作ってあげればいいだけです。以下のスクリプトを用意しました。

const fs = require('fs');
const path = require('path')

const generateFile = (pathname, filename) => {
  const absolutePath = path.resolve(__dirname, pathname);
  const filePath = `${absolutePath}/${filename}`;

  if (!fs.existsSync(absolutePath)){
    fs.mkdirSync(absolutePath);
  }

  if (fs.existsSync(filePath)){
    console.log(`Error: ${filePath} already exists.`);
    return;
  }

  fs.appendFile(filePath, "// created by generator.", function(err) {
    if (err) { return console.log(err); }

    console.log(`${absolutePath}/${filename} generated.`);
  });
};

const generateComponent = (componentLevel, componentName) => {
  const filenames = ['index.tsx', 'styles.scss', 'styles.scss.d.ts'];

  filenames.forEach(filename => {
    generateFile(`../src/components/${componentLevel}/${componentName}`, filename);
  });
};
const generateStory = (componentLevel, componentName) => {
  generateFile(`../stories/${componentLevel}`, `${componentName}.tsx`);
}; 

const run = () => {
  const [processName, scriptName, ...options] = process.argv;
  const [componentLevel, componentName, ...undefinedOpts] = options;
  const validComponentLevels = ['atoms', 'molecules'];
  if (validComponentLevels.includes(componentLevel)) {
    generateComponent(componentLevel, componentName);
    generateStory(componentLevel, componentName);
  } else {
    console.log(`Error: コンポーネントレベルは${validComponentLevels.join(', ')}のいずれかにしてください`);
  }
}

run();

実行すると、必要なファイルが生成されるようになりました。

~/boron-web node scripts/componentGenerator.js atoms Hoge
/Users/gaaamii/boron-web/src/components/atoms/Hoge/styles.scss.d.ts generated.
/Users/gaaamii/boron-web/src/components/atoms/Hoge/index.tsx generated.
/Users/gaaamii/boron-web/src/components/atoms/Hoge/styles.scss generated.
/Users/gaaamii/boron-web/stories/atoms/Hoge.tsx generated.

Storybookの認識が曖昧(何に使うものなのか、今どうなってるのか)

今回のこのブログを読んでもらって、ちゃんと整理できたので活用していきましょうという感じにしていきたいです。社内のesaにも、補足があればどんどん書き足していきたいです。

ついでに:latest(5.2.3)に対応

ついでに、Storybookのバージョンも最新に上げました。

まとめ

以上、今回は4つの作業を行いました。

f:id:shgam:20191017100348p:plain
今回行った作業

当たり前にやるべきことをできてなかったという感じなので、ここで整理できてよかったです。

せっかくコンポーネントを分けているので、他の人が画面を実装するときには「Storybook見ながらコンポーネント組み合わせたら実装できた!」みたいな体験になればいいなと思っています。

スタディプラス AndroidアプリKotlin化の歩み

こんにちは、Androidチームの若宮(id:D_R_1009)です。 今回はAndroidアプリの大きな更新、JavaからKotlinへの移行について書きたいと思います。

Androidアプリの歴史

Kotlinの導入

スタディプラスのAndroidアプリは2016年1月ごろにフルリニューアルを行い、そのまま開発を続けています。 Kotlinは2017年12月ごろの導入となるため、コードの大半はJavaで記述されています。

その後、2018年3月ごろから本格的にKotlinへの移行(コードのKotlin化)を進め、8月ごろには20%を占める程度になりました。

tech.studyplus.co.jp

Kotlin化の本格化

2018年9月よりフルタイムの開発者が2名に、2019年5月より3名になりました。 また副業でkobakeiさん(id:keisukekobayashi)に入ってもらったことにより、Kotlin化が本格化します。

以下、大きな変更や方針が決まった時期を振り返ってみました。 もちろん、合間合間にリファクタリングやマルチモジュール化に伴うコードの整理が行われています。

  • タイムラインデザインリニューアル(2019年10月)
  • Kotlin Coroutines導入、RxJavaから移行開始(2018年11月)
  • デザインリニューアル(2018年11月)
  • マルチモジュール構成へ移行開始(2018年12月)
  • 友達からフォロー/フォロワーへの更新に伴うアプリの一新(2019年3月)
  • 大学情報関連画面のリファクタリング(2019年3月)
  • 内部DBにRoomのDatabaseViewを導入(2019年5月)
  • AndroidXへの移行(2019年6月)
  • NavigationによるFragment遷移実装開始(2019年7月)
  • アカウント作成方法更新(2019年8月)
  • ネットワークレスポンス用DataクラスのKotlin化 (2019年9月)

結果として、2019年9月末を持ってKotlinが全体の86%を占める状況となりました!

f:id:D_R_1009:20190930181835p:plain

ここに至るまでに大きな影響を与えた出来事について、いくつか抜き出してみたいと思います。

Kotlin Coroutines導入、RxJavaから移行開始(2018年11月)

Kotlin Coroutinesのstable版が2018年10月にリリースされ、AndroidチームではまずSDKに導入しました。 下記ブログを導入直後に書いたことを覚えています。

tech.studyplus.co.jp

SDKへの導入に続いて、スタディプラスへKotlin Coroutinesを導入しています。 RxJavaを利用していた箇所が多かっため、RxJavaをKotlin Coroutinesに置き換える処理が大半となりました。

RxJavaは下記のような目的で利用されていました。

  1. Single / Complete 型による通信
  2. RxBusによるクラス間連携
  3. Obserbable によるリスト操作

通信処理をOkHttp + Retrofitで行なっていたため、Kotlin化を簡単に進めることができました。 suspend を返り値とする対応はRetrofitのアップデートを待ってからとなりましたが、デフォルト引数の利用などだいぶコードの削減ができるようになりました。

2019年7月頃からRoom 2.1でKotlin Coroutinesがサポートされたため、Kotlinをより活用しやすくなっています。 またKotlin Coroutines 1.3.30からは Flow も導入されたため、 RxStream の処理も移行しやすくなりました。

Kotlin Coroutinesが登場したことにより、既存コードに +α を加えながらKotlin化しやすくなったと言えます。

マルチモジュール構成へ移行開始(2018年12月)

kobakeiさんには月1回勉強会を開いてもらっています。 その2018年11月のテーマが「マルチモジュール」でした。

当時のスタディプラスアプリはJavaとKotlinを合わせて10万行程度(Java 7.5万、Kotlin 2.5万)のシングルモジュールアプリでした。 設計はJavaのコードがActivityを中心としたMVC、KotlinのコードがAndroid Architecture Moduleを利用したMVVMが採用されていました。

当時開発していた時に上がっていた問題は、下記3点です。

  1. ビルド時間が長い
  2. 画面ごとに利用するメソッドがまとまっているため、処理がまとめられていない
  3. リファクタリング時に思わぬクラスへの影響が発生する

マルチモジュールに移行する際、一番期待していたのは「ビルド時間」の問題でした。 確かにマルチモジュール化により並列ビルドの恩恵を得られたのですが、同時にDaggerを導入したことにより相殺されてしまったのか、ビルド時間の短縮は感じられませんでした。

一方で、設計上は大きなメリットが得られました。 モジュール化を進める上で、まず entity (データクラス)モジュールから分離する必要があります。

スタディプラスアプリの場合、この entity モジュールの作成が難航しました。 というのも、データクラス内でネットワークインスタンスを呼び出すなどの処理をしている箇所が散見されたためです。 Kotlin化の早いタイミングで設計上の問題が見つかったため、結果として効率的にKotlin化を進めることができました。

一方で、クックパッドさんが行なっていた Legacy モジュールの対応は行えませんでした。 こちらは色々とモジュール移動に苦心することとなったため、行なっておけばよかったと強く後悔しています。

speakerdeck.com

マルチモジュール化と同時にアプリ全体を巻き込む機能開発(フォロー制への移行)が被ってしまったため、タイミングを逃してしまったことが大きかったように思います。 マルチモジュール対応を行う場合には、新規機能開発のタイミングと被らせずにスタートするのが良いのではないでしょうか。

1年間を通して見ると、kobakeiさんにマルチモジュール化の導入から実行までを強く推進してもらいました!

f:id:D_R_1009:20190930182212p:plain

マルチモジュール化によりKotlin化しやすくなる(クラス間の依存関係が一方方向になるため、影響範囲が限定される)ことを実感しています。 ビジネス的な成果は少ないのが少々難しいところですが、開発チームのタスクとして取り組むことを強くお勧めします。

ネットワークレスポンス用DataクラスのKotlin化 (2019年9月)

Kotlin Coroutines 1.3.30やOkHttp 4系を導入しようとしたところ、Proguardを起因とするビルドクラッシュが発生しました。 このため、ProguardからR8へ移行した方が良い状況となりました。

github.com

github.com

しかし、R8でGsonを利用すると問題が生じやすくなります。 この問題に対応するため、1週間ほどかけて全ての通信用データクラスをKotlin Dataクラスに変換しGsonからmoshiへ移行する対応を行いました。

r8.googlesource.com

また逆説的ではありますが、OkHttpやRetrofitなどのライブラリ側でKotlinが利用されるようになってしまったため、Kotlinの対応を見越した開発体制にする必要が生じています。 例えばKotlin CoroutinesのMainDispatchersの初期化遅延問題は、最新のR8(記事執筆時点でalpha版であるAGP 3.6以上)でなければ解決しません。

github.com

こういった大規模な問題が発生するまでデータクラスの整理を後回しにしていたので、少々タスクが重い状況になってしまいました。 Kotlin化を進める中で、少しずつサーバーチームと連携しながら進めていくのが良いように思います。

また知見としては、通信用のデータクラスのKotlin化をすることで下記のような事象に出くわしました。

  1. 古くからあるAPIのため特に理由もなくnullableとして扱っているプロパティが見つかった
  2. デフォルト引数により、non-nullな値として扱える箇所が複数見つかった
  3. Gsonではリフレクションにより継承関係を簡単に扱えたが、moshiでは継承関係をデータクラスの引数として表現する必要があった

2つ目は特にリストをプロパティとして持つJSONに有効でした。 これまでは orEmpty() を噛ませることで対応していた箇所が、デフォルト引数で emptyList() を指定するだけで対応が終わるようになります。 結果論ではありますが、型安全なコードを記述するためにも、Kotlin化は非常に有効な手段だと言えるのではないでしょうか。

終わりに

簡単ではありますが、スタディプラスアプリが1年ほどかけて60%ほど(削除しているコードを考えるとそれ以上! )をKotlin化した経験を振り返ってみました。 Kotlin化により、コードレビューの時に名前付き引数があるとレビューしやすいなど、様々なDXの向上を感じています。 機能開発の傍らであってもKotlin化を進めることを快諾してくれた企画部やCTO、並びにチームメンバー(中島さん、隅山さん)と副業エンジニア(kobakeiさん)にはいくら感謝しても感謝しきれません!

残り10%強のKotlin化、ならびによりユーザーにとってメリットのある設計を目指して、引き続き頑張っていきたいと思います。

FlutterとFirebaseで新しいサービスをリリースしました

こんにちは、スタディプラスの須藤(id:kurotyann)です。 タイトルどおり、9/17にFlutterとFirebaseで新しいサービスをリリースしました。

サービス名は「ポルト(Porto)」です。 受験生に人気の参考書を月額980円でスマホで読める電子参考書サービスです。 iOSとAndroidで利用でき、無料で読める参考書もあります。受験生でない方も試しにインストールしてみてください。

apps.apple.com

play.google.com

【公式】ポルト 参考書読み放題サービス【14日間無料お試しのお申し込みはこちら】

さて、リリースされたばかりのポルトですが、今回のブログでは以下の3点を書きます。

  1. 「(1) 技術スタック」
  2. 「(2) 開発期間」
  3. 「(3) FlutterとFirebaseで開発を考えている人へ」

なお、技術の詳細や知見は、今後のFlutterやFirebase関連のMeetupと、12月のアドベントカレンダーで共有する予定です。

今回のブログの目的は、FlutterとFirebaseというホットな技術の採用事例の共有です。

(1) 技術スタック

ポルトには、3つのプロダクトがあります。

  1. iOSとAndroidのモバイルアプリケーション
  2. データ(参考書 etc)をFirebaseにインポート・エクスポートするスクリプト
  3. ランディングページ(LP)とクレジットカードの登録フロー(クレカ登録)をもつWebアプリケーション

ポルトは月額980円のサブスクリプションサービスです。スマホアプリでサブスクリプションの登録はできず、Webサイトで登録します。つまり、NetflixやSpotifyと同じくスマホアプリには課金登録がないサービスです。

そして、1. と 2. は同じリポジトリでコードを管理したので、GitHubのリポジトリは全部で2つです。

iOSとAndroid、データのインポート・エクスポート

まずは、スマホアプリの技術スタックです。 GitHubのCodeタブがわかりやすいので、そのスクショを使って説明します。

post_tech_stack_map.001.jpeg (238.6 kB)

post_tech_stack_map.002.jpeg (122.1 kB)

Dartの割合は、ほぼ100%です

JavaScript 7.2%は、データのインポート・エクスポートのコードです。Firebase Admin SDKのNode.jsで書いています。TypeScriptで書けてないのは私の力不足なので、今後の課題です。そして、Ruby 1.1%はfastlaneのコードです。

つまり、データのインポート・エクスポートを別リポジトリで管理していれば、Dartはほぼ100%になります。SwiftとKotilnを書いたのは、弊社のStudyplus SDKを利用するために、Flutter Plugin Packageを書いたときだけです。

iOSとAndroidを開発するときはAndroid Studioを使い、データのインポート・エクスポートを開発するときは、IntelliJ IDEAを使っています。

当初はIntelliJ IDEAだけで開発しようと試みましたが、IntelliJ IDEAのFlutterプラグインが不安定なため断念しました。

ただ、iOSとAndroidの開発とデータのインポート・エクスポートを同時に開発することは、稀だったので開発効率には、ほとんど影響はなかったと思います。

バックエンドはFirebaseで固めた

見ての通り、Firebaseを使いまくっています。FlutterとFirebaseの相性はとても良く、公式プラグインはだいたい存在します。

公式プラグインの安定性は、十分に利用できる安定性です。まったくデグレなく安定してるのかと言われるとそうではなく、発展途上な部分やバグはあります。しかし、利用した方が圧倒的に便利で安全だと言ってよい性能です。

公式プラグインで利用しなかったのは、Firebase Crashlytics です。ポルトでは、iOSのみビルドがうまく通らず、クラッシュの解析はSentryに任せてしまいました。ただ、Dartの割合が大きいためSentryだけで、なんとか解析は進められないかと考えています。これも今後の課題の一つです。

Webサイト(LPとクレカ登録)

次は、Webサイト側の技術スタックです。

post_tech_stack_map.004.jpeg (214.8 kB)

Nuxt.jsとFirebase Hostingを使いました

Nuxt.jsの nuxt generate で静的なウェブアプリケーションを生成して、成果物をFirebase Hostingへデプロイしています。iOSとAndroidのユーザーでログインする必要があるのと、StripeのAPIを呼ぶだめに、こちらでもバックエンドはFirebaseです。

クレジットカードの登録はStripeのBillingです。Stripeとの連携はFirebase functionsを使って実現しています。APIの呼び出しは onRequest ではなく、SDK経由の onCall です。一方、StripeのWebhookと連携する場合は、onRequest です。

StripeとFirebase functionsの実装は試行錯誤があったので、今後どこかで発表したり記事にまとめたりして、ほかの開発者の意見を聞きたいところです。

CI/CDを同じ技術スタックで統一した

スマホ側と同じく、Web側もCircleCIとfastlaneでCI/CDをまとめました。弊社がCircleCIで一本化していることと、私がfastlaneに慣れていることが理由として大きいです。

iOSやAndroidでなくとも、Webでも細かいCI/CDフローをfastlaneが担ってくれたので、個人的にこの構成に不満はありません。

(2) 開発期間

開発期間も、GitHubのInsightsタブがわかりやすいのでスクショで説明します。 モバイルとWebの両方を縦に並べてみました。

post_tech_stack_map.003.jpeg (185.8 kB)

post_tech_stack_map.005.jpeg (227.7 kB)

開発期間は2月~9月(モバイル)と、6月~9月(Web)

Flutter 1.0.0の公表は、2018年12月4日のことでした。このとき、私はポルトの要件定義とプロトタイプを開発していました。当時のプロトタイプは、iOSのみでSwiftとFirebaseという構成でした。

当初は、iOSを先にリリースして、Androidは後からリリースする計画でしたが、同時にリリースしたいという要望が出てきました。このとき私には、Androidの開発経験がありませんでした。さらに弊社のAndroidエンジニアをStudyplusの開発から、新規事業のポルトへコンバートするのは、人数と計画から考えて難しい状況でした。

そこに、Flutterを個人で触っていたAndroidエンジニアの若宮(id:D_R_1009) が「Flutterなら開発できるかもしれない」と、アドバイスをくれたのがきっかけで、2月からFlutterでの開発をスタートしました。

フルタイムでポルト(Flutter)に関わったのは6月から

2月から9月の約8ヶ月間ですが、フルタイムで開発をスタートできたのは、6月からです。5月に大石(id:k_oishi)が入社したことで、iOSの開発をバトンタッチして新規事業へフルコミットすることができました。それまでは、Studyplus iOSの開発と採用活動を同時に行っていました。

開発スピードが求められる新規事業でありながら時間がかかっているのは、このような社内の人員状況が原因です。また弊社の新規事業部は、私と竹内の他に営業とコンテンツ制作を担当する2名の社員がおり、合計4名の社員でポルトを開発しました。

FlutterとFirebaeを採用してスピーディな開発を検討している方は、弊社のこのような状況を考慮した上で検討してもらうと良いと思います。

Webサイトはデザイナーと共に開発

デザイナーの竹内が5月に入社して、Nuxt.jsでのWeb開発を6月からスタートしました。Nxut.jsで開発することは、エンジニアの私ではなくデザイナーの竹内が希望しました。

まずは、ランディングページ(LP)の作成と全体のレイアウト構成を竹内が行い、7月ごろから私がFirebaseの連携と、クレジットカード登録フローを開発しました。

竹内は名古屋からのリモート勤務であり、東京のオフィスに来るのは月に1度だけです。コミュニケーションはSlackとZoomを使っています。

スピードが求められる新規事業でリモート開発は難しいのではと不安もありましたが、結果的に開発は間に合いました。

(3) FlutterとFirebaseで開発を考えている人へ

最後に、ここまでの説明をもとに「弊社と同じようにFlutterとFirebaseで開発を考えている人」へいくつか共有したいことを書きます。

  • Flutterを使えば、ほぼDartを書くだけでiOSとAndroidのネイティブアプリが開発可能です
  • Flutter用のFirebase公式プラグインは十分に利用できる性能だと思います
  • Flutterの利用者が国内外で増えているのをissueの数や、検索でヒットする良記事の数で感じます。なので困ったことがあっても、なんとかなりますし、なりました

最後に

サービスのリリースは、ゴールではなくスタートです。

多くのユーザーの要望に応えられるサービスへ成長できるよう、これからも開発を続けていきます。

Studyplus iOSでライブラリ管理をCocoaPodsからCarthageに移行した件

こんにちは。今年の5月に入社したiOSエンジニアの大石(id:k_oishi)です。 今回は弊社がリリースしているStudyplusのiOSアプリのライブラリ管理をCocoaPodsからCarthageに移行した件をご報告します。

プロジェクトの構成と開発PCのスペック

現在のStudyplus iOSは以下の構成となっています。

  • 開発環境: Xcode 10.3
  • 言語: Swift, Objective-C(割合は86:14)
  • ライブラリ管理: CocoaPods, Carthage
  • CI/CD: fastlane, CircleCI, DeployGate

また、私が入社時に希望して用意されたMacBook Proのスペックは以下のとおりです。 f:id:k_oishi:20190913153002p:plain

気になるライブラリのビルド時間

私が入社した時点でCarthageの導入はされていましたが、Carthageで管理されていたライブラリは一部のみでした。 ほぼ全てのライブラリがCocoaPodsで管理されている状態でした。

そのような状態で開発を進めていましたが、クリーンビルドで5分以上の時間がかかり、ちょっとしたコードの修正やブランチの切り替えの際にライブラリのビルドが走るのは結構つらいものがありました。

f:id:k_oishi:20190913153121p:plain

そこで私は過去に経験したプロジェクトでもCarthageへの移行の経験がありましたので、チームメンバーと相談してCarthage移行を進めることになりました。

Carthage移行のはじまり

まず、現在CocoaPodsで管理しているライブラリからCarthageに対応しているライブラリを洗い出しました。 以下のライブラリが対応していましたので、1つずつ順次進めて行きました。

  • Apollo
  • Facebook SDK
  • Firebase
  • Nuke
  • Realm
  • SVProgressHUD

    特定のライブラリのビルドがうまくいかない件

    Carthage移行を進めていく中でビルドエラーに遭遇しました。 f:id:k_oishi:20190913153251p:plain

このエラーは以下のライブラリの移行中に発生しました。

  • Facebook SDK
  • Firebase
  • Realm

Argument list too long(コマンドの引数が長すぎる)というエラーのようですが、ライブラリのビルドについてあまり詳しくない人にとって、なぜこれが起きたのか全くわかりません。ただ、なんとなくですが、同じような引数のパスがひたすらループしているように見えました。(このスクリーンショットは一部分で全体はこの数十倍の量)

プロジェクトの設定の変更

f:id:k_oishi:20190913153333p:plain

プロジェクトの設定をひたすら見直していたところ、FRAMEWORK_SEARCH_PATHS$(SRCROOT)recursiveになっているのがビルドエラーの原因かもしれないことがわかりました。まず既存のコードでnon-recursiveに変更してビルドが通るかを確認してから、Carthageの移行を行いビルドできることを確認しました。

(補足) CarthageでのFirebase導入の注意点

Firebaseの各ライブラリをCarthageから導入する場合は以下のようなJSONファイルをCartfileに指定し、バイナリ形式でダウンロードされる仕組みです。

binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json" == 6.7.0
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseDynamicLinksBinary.json" == 6.7.0
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAdMobBinary.json" == 6.7.0
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseRemoteConfigBinary.json" == 6.7.0

なお、Firebaseの各frameworkはStatic Libraryのため、従来のライブラリに必要なcopy-frameworksの手順は必要ありません。 また、導入するFirebaseの機能によっては追加で関連するライブラリ等をLink Binary With Librariesに追加する必要があります。

詳細はこちらのエントリを参考にしてください。 Crashlytics をどうしても Carthage で使いたいあなたへ

(補足) LicensePlistの設定変更

アプリで使用しているライブラリのライセンス情報の表示にLicensePlistを使用している場合、CocoaPods使用時に取得できていたライセンス情報がCarthage移行後に取得出来なくなる場合があります。 今回のケースではJSONファイルに記述されたバイナリを取得しているFirebaseが該当します。

このような場合、Firebaseのライセンス情報を表示するためにlicense_plist.ymlを作成して以下のような記述を追加しました。これでこれまでと同様にライセンス情報が表示されるようになりました。

github:
  - owner: firebase
    name: firebase-ios-sdk
    version: 6.70.0

rename:
  firebase-ios-sdk: Firebase

以上でローカルの開発PC上のCarthageへの移行が完了しました。

Carthage対応のまとめ

結果、ローカルの開発PCでは以下のようにビルド時間を短縮することができました。 移行前 5分〜6分移行後 1分40秒〜2分

もちろん初回は$ carthage bootstrap~の実行が必要ですので、その分のビルド時間はかかるのですが、開発の最中にライブラリの再ビルドが走ることはなくなり快適に開発を行えるようになりました。

今回の移行では以下がポイントとなりました。

  • 1ずつ移行を試してビルドエラーの原因を特定しやすくする
  • ビルドエラーが出る場合はプロジェクトの設定を見直す
  • Firebaseの導入は他と少し違うので要チェック
  • ライブラリによってはLicensePlistの対応が必要になるかも

CIの改善

CircleCIでのCarthageのキャッシュ利用

ローカルの開発PCでの移行が完了しましたので、CircleCIの設定を変更してCarthageのビルド結果をキャッシュするようにします。 キャッシュの設定をしないと毎回Carthageのビルドが走り、ローカルの開発PCと比べるとCI環境ではとんでもないビルド時間が毎回かかってしまいます。

f:id:k_oishi:20190913153428p:plain

キャッシュを利用するためにはconfig.ymlに以下のステップを追加します。

  setup_carthage:
    steps:
      - restore_cache:
          key: v1-ca-{{ checksum "Cartfile.resolved" }}
      - run:
          name: Carthage
          command: carthage bootstrap --platform iOS --cache-builds --no-use-binaries
      - save_cache:
          key: v1-ca-{{ checksum "Cartfile.resolved" }}
          paths:
              - Carthage

キャッシュを利用することで初回のみはそれなりの時間がかかりますが、ライブラリに変更がない場合は以下のように数十秒でCarthageの設定を終わらせることが出来るようになりました。

f:id:k_oishi:20190913153455p:plain

さらなるCIの高速化を求めて…〜CocoaPods〜

Carthage導入後のCIの結果を眺めていたところ、もう少しビルド時間を改善できそうな部分を見つけました。CocoaPodsのステップです。

f:id:k_oishi:20190913153659p:plain

このステップで時間を要していたのがCircleCIが独自に用意したコマンドです。これはCocoaPodsのリポジトリの取得を従来より早く取得できるというものでした。 curl https://cocoapods-specs.circleci.com/fetch-cocoapods-repo-from-s3.sh | bash -s cf

しかし、CocoaPodsは少し前にリリースされたv1.7からCDNに対応しました。これによりリポジトリを取得する必要がなくライブラリを導入できるようになりました。要するに前述のコマンドを実行する必要が無くなったのです。このコマンドの実行を削除した結果、以下のように当該ステップの時間を短縮することができました。

f:id:k_oishi:20190913153739p:plain

CI高速化の結果

Carthage移行前は毎回ビルドに20分近くかかっていましたが、Carthage移行後のキャッシュが効いた状態では8分程度でビルドが終わるようになりました。

Carthage移行前 f:id:k_oishi:20190913153811p:plain

Carthage移行後 f:id:k_oishi:20190913153839p:plain

いかがでしたか?

今回のCarthageへの移行を行ったことで、開発時とCIのビルド時間を短縮することができました。

ビルドエラーが発生すると解決するのがやや大変ではありますが、ライブラリのより深い世界を知るきっかけにもなるかと思います。 現在もCocoaPodsでライブラリ管理されているプロジェクトもあるかと思いますが、ぜひ試されてはいかがでしょうか。

先日のiOSDC Japan 2019の以下のセッションではCarthageやCocoaPodsで使用されるライブラリやフレームワークに関する解説やビルドエラーの際の原因の切り分け方法がわかりやすくまとまっており、大変参考になる内容でした。

また、今後ライブラリ管理の選択肢の1つになりそうなSwift Package Manager(SwiftPM)の動向もチェックしたいと思います。

iOSDC Japan 2019に行ってきました

こんにちは、Studyplus iOSチームの明渡(id:m_yamada1992)です。

iOSDC Japan 2019(2019年9月5日〜7日)にiOSチームのうち2名(大石、明渡)で参加いたしました。 なお、費用については下記のスポンサー枠1名 + 弊社の 勉強会・カンファレンス参加補助 で参加させていただきました。

f:id:m_yamada1992:20190918193247j:plain

私自身ルーキーズLTにプロポーザル提出してたのですが、残念ながら不採択だったので参加補助を利用。 iOSDC初参加初登壇は叶わなかったものの、めげずに来年以降もまたチャレンジしたいなと思います!

iOSDC Japan 2019 にスポンサード

iosdc.jp

スタディプラスはシルバープランでスポンサーとして、トートバック内にノベルティ提供をさせていただきました。 参加した方は、弊社ロゴ入りを付箋をゲットしたはず。

f:id:m_yamada1992:20190918194210j:plain

感想

参加メンバーそれぞれで記載いたします。

明渡

当日参加したセッションの中で、とても印象に残ったセッションについて感想を記載いたします。

Heart of Swift @Yuta Koshizawaさん

fortee.jp

正直なところ、このセッションの内容をほとんど知らなくても、なんとなく書いてなんとなく動くアプリをSwift言語をもって作れてしまう。実際、私がそうでした。

JavaやPythonなど他の言語も少々書いていたことがありますが、Swiftがなんとなく書きやすくて好きだなと感じていた根拠が凝縮された内容で、Swiftにより愛着が湧きました。

Reference SemanticsよりValue Semantics、プロトコルは型としてより制約として使うことを優先して検討するというお話は今後積極的に意識しながらソースコードを書く所存です。

色の難しい話に負けない体づくり60分 @ しもとりさん

fortee.jp

先日のtry! Swift Tokyo 2019で発表のあったアクセシビリティのためのカラーコントラストをきっかけに、ありとあらゆる理解を投げ出したくなる色にまつわる事柄を分かりやすくまとめあげたお話。 自分は上記の発表を聞いた際に「色に関する基準の存在を知ったので、ダークモード対応時もこれをもとになんとかできるだろう」と細かい話を理解するのは諦めてました。

なので、これだけ掘り下げて理解して、しかも発表用に情報を整理してまとめあげるって凄まじいなと尊敬の念を覚えました。

尊敬の念止まりにせず、自分も得た知見で少しでももやっとした点は積極的に掘下げていかねばなと反省しました・・・

なお、こちらのセッションの内容はダークモード対応時にフル活用させてもらうだろうなと想像してます。

すべての人のためのアクセシビリティ対応 @akatsuki174さん

fortee.jp

アクセシビリティ対応をすると発生する恩恵、対応するには具体的に何をすればよいのか、そして対応を進める上での具体的なアクションまで言及していたお話。

弊社のStudyplusのiOS版を文字サイズ変更してざっと確認してみたところ、textStyle設定済みで可変表示される箇所とそうでない箇所が入り混じっていました。

根本的に文字サイズが可変することを想定していないレイアウトもそこそこあり、それらも見直しながらだと気が遠くなり着手するのが恐ろしい・・・

ですが、今回得た知見をもとに気づいたところから少しずつチーム内にIssueを起票するところからやってみたいなと思います。

利用ユーザーが元気な若年層多めのアプリなのでどうしても優先度は上がらない気がするのですが、議論するタネがあるのとないのとじゃ大分違うはずなので。

全体的な感想

今年3月のtry! Swift Tokyoに続き、初参加した技術カンファレンスでした。 どこからこんなに湧いてきたんだろうという参加者数に圧倒されたり、協賛している企業さんがずらりと並ぶブースに圧倒されたり。

自分は真面目に参加しなかったんですが、iOSDCチャレンジという某隠れネズミキャラクターを探し歩く様子を彷彿とさせるイベントでめちゃめちゃ盛り上がってたりしましたね。圧倒されっぱなしでした。

前夜祭で職場から参加しに向かう際、 「技術カンファレンスはお祭りだよ。楽しんでおいで」 と先輩エンジニアのかたに声かけてもらったんですが、文字通りお祭りだったなぁと思います。

大石(id:k_oishi)

素晴らしいセッションばかりでしたが印象に残ったセッションの感想です。

ライブラリのインポートとリンクの仕組み完全解説

fortee.jp

ライブラリのリンクについては、iOSでCarthage使っている人ならかならず遭遇する謎のビルドエラーで馴染深い話題かと思います。 このセッションでは複数あるライブラリの形式が説明され、インポートとリンクがどのように行われるかという興味深い解説を聞くことが出来ました。 また、実用できそうで良いと思ったのが発表資料の最後のビルドエラーでの問題解決YES/NOチャートです。 ライブラリ導入時のエラーが発生した際に使用できる内容で大変参考になりました。

実機の管理とおさらば!AWS Device FarmでiOSのテストをしよう!

fortee.jp

以前、私が所属していた会社で過去にAndroidエンジニアを担当されていた白山さんのセッションでした。 まず、良いと思ったのがセッションの構成です。 前半がXCTestとXCUITestを使ったユニットテストの基礎を解説しつつ、後半がAWS Device Farmを使用した自動テストの実行方法の解説となっていました。 この構成によってユニットテストや自動テストにそこまで詳しくない方へのフォローをしつつ、うまくAWS Device Farmの話題に繋げていました。 AWS Device Farmの概要が理解できましたし、発表方法のテクニックとしても参考になったセッションでした。

セッション終了後に白山さんに質問した内容は以下のとおりです。

  • 200USD/月で使い放題の使い放題のプランについて 250USD/月で1デバイススロット割り当てられ、1端末使ったテストが使い放題となる →複数同時実行したい場合は250USD * デバイススロット数のお金がかかる
  • テストが実行されるまでの待ち時間 基本的に待ち時間はない、OSとデバイスの組み合わせが希少な端末は開始まで多少待つことがあるかも

個人開発のアプリが輝くために

fortee.jp

資料 https://speakerdeck.com/ahiru/for-personally-developed-apps-to-shine

LTにて個人開発向けで有益なノウハウが共有されました。 広告費がかけられない個人開発でダウンロード数を増やすためのASO対策を知ることが出来ました。 主なポイントは以下のとおりですが、それ以外にも貴重なノウハウがありましたので興味のあるかたは資料をご覧ください。

  • タイトル・サブタイトルの両方にメインワードを入れる
  • キーワードにひらがな、カタカナ、漢字を含めて検索ワードの表現揺れ対策
  • 高評価してくれそうなユーザーにレビュー誘導を出す

私自身の個人開発のアプリにもすぐに取り入れられるものが多いと感じました。

TBD

fortee.jp

Podcastでお馴染みRebuild.fmにレギュラー出演されている@hakさんとiOSDC実行委員長@tomzohさんによるセッションです。 まず、セッションはiOSに全く関係ありません。 過去の家庭用ゲーム機を振り返って画面の表示形式や音声の出力形式、入力機器などの技術の進化を語り合うという内容でした。 最近、色々な言語で家庭用ゲーム機のエミュレーターを実装するのが流行っていたりしますので、スプライトの表示方法やスキャンラインの仕組みなど楽しく聞くことが出来ました。 ゲーム好きには丁度良いセッションでした。 すでに動画が公開されていますので、興味のある方はご覧ください。

iOSDCチャレンジ

iOSDCの会場や公式サイト、スポンサー企業の事前ブログや企業ブースなどに隠されているトークン(#で始まる文字列)を自分のプロフィールページに入力するとスコアが加算され参加者が表彰されるというイベントがiOSDC開催中にありました。

このイベントの目的はスポンサー企業のブログを参加者に見てもらう、企業ブースをしっかり回ってもらうという意図があったと思うのですが、それなりに機能していたように感じました。 会場やWebサイトでリアルタイムのランキングが表示されており、上位の方々がすごいことになっていました。 私の成果も念のため共有いたします。

  • 瞬間的にトップになった図

f:id:m_yamada1992:20190919131641j:plain

  • 最終的な順位

f:id:m_yamada1992:20190919131714j:plain

面白い試みだと思いましたので次回も期待したいと思います。

全体的な感想

今回は自社がスポンサーしていることもあり、前夜祭から参加しやすく、最終日までフルで参加することが出来ました。 その結果、これまでのiOSDCよりカンファレンスを楽しめたと思います。 懇親会でもたくさんの方とお話する機会があり美味しい食事とビールを楽しむことが出来ました。 そろそろ私も登壇する努力をしたいと思います。

さいごに

登壇してくださったスピーカーのみなさま、運営スタッフのみなさまのご尽力があってこそ、不自由なく楽しい時間を過ごせたと思っています。どうもありがとうございました!

来年も無事開催されるようでしたら、是非とも参加したいと思います。

Google Developers ML Summit Tokyo : Human-Centered Machine Learningに参加しました

こんにちは、Androidエンジニアの若宮(id:D_R_1009)です。 先日、Google社で開催されたGoogle Developers ML Summit Tokyo : Human-Centered Machine Learningにインフラエンジニアの菅原(id:ksugahara08)と共に参加してきました。

f:id:D_R_1009:20190918191752j:plain

events.withgoogle.com

今日は、それぞれの感想とスタディプラス内の機械学習への取り組み状況について、簡単にお伝えできればと思います。

Google Developers ML Summit Tokyo

Google I/O 19で発表されたPeople+AI Guidebookを解説し、補助してくれる会でした。 機械学習をプロダクトへ取り込む際に考えることや、導入のステップなどを聞くことができたように思います。

pair.withgoogle.com

有志の方による日本語訳 : 人にうれしいAIのためのUXデザインガイド(People + AI Guidebook)

f:id:D_R_1009:20190918191839j:plain
すてきなピンバッチ

また9月17日にはワークショップも行われていたのですが、今回はML Sumit Tokyoのみの参加です もっと機械学習に取り組めるようになったら、デザイナーの方と一緒にワークショップに参加したいと思います。

developers-jp.googleblog.com

感想

以下、参加した2名の感想です。

若宮(id:D_R_1009)

機械学習熱が最近高まってきたので参加してきました。

個人的に面白いな! と思ったのはMLとMaterial Designのセッションです。 Object DetectiveのLive Camera用に新しくMaterial Designのパーツが追加されただけにとどまらず、ユーザーが「自然」に感じられるように操作を作っていくかは、日々の開発で活用できそうだなと感じました。 またちょっと敷居が高く感じていたMaterial Themeのカスタマイズについて、少し理解が進んだようにも思います。

全体を通して「ヒト」と「AI」の関わり方をGoogleが模索していることについて考える、非常に面白いサミットだったように思います。 AIやDataの透明性を示すことは、開発者ではなく利用者としても考え続けるテーマだと思いました。 ML KitなどでAIをアプリに組み込むか、それともバックエンドのサービスが利用するのかはわかりませんが、常々考え続けていきたいなと思います。

菅原(id:ksugahara08)

弊社サービスでもMLの利用を見越して、参加してきました。 (前日のPyConJP2019スタッフで疲れて少し寝坊しました笑)

今回のテーマは「公平性」「透明性」だったと思います。 いかに、エンドユーザーに差別意識を持たれないような公平なサービスを作るべきかという倫理観にも近い話を聞けてとても貴重な知見を得られました。 もちろん万人に受け入れられるサービスは難しく、コストと精度のトレードオフという話もあります。また、十分なデータを持たないことで意図しないバイアスがかかってしまうこともあるかもしれません。

それでも諦めずフィードバックから改善していく大切さ、エンドユーザーに説明をする透明性の大切さを聞けて学ぶ喜びでした。 次回もできれば参加したいと思います!!

スタディプラスの機械学習取り組み状況

最後に、スタディプラスが今機械学習へどの程度取り組んでいるかを簡単にまとめたいと思います。

弊社の状況としては、機械学習の学習を有志(12名ほど)が始めたところになります。 会社のSlackにチャンネルを作成し、昼休みの時間を利用して週2~3回集まって自習の時間を作っています。

きっかけはML Study Jams Vol.3です。

events.withgoogle.com

業務や家庭の事情などがあるためなかなか時間の確保が難しいのですが、1コースを大半が修了できそうな状況になってきました。 このコースで学んだことをベースに、機械学習を業務にどう取り入れていくかを考えられればと思っています。

終わりに

二週間ほど前に「この日にサミット参加したいです!」と相談したところ、快く送り出してくれたチームの皆様に感謝!

builderscon 2019に行ってきた

今回は8/29~31に開催された builderscon tokyo 2019 へ行ってきた感想を書きます。

f:id:yo-shimada:20190905173056j:plain
参加メンバーの写真

はじめに

buildersconへの参加は2年連続です。昨年の感想はこちらになります。

tech.studyplus.co.jp

またスタディプラスは昨年に続きbuildersconのスポンサーとして、ネームカードスポンサーとウォーターボトルスポンサーとして協賛をさせて頂きました。

感想

buildersconのセッションはバリエーションに富んでおり、どの発表も大変興味深いものでした。その中でも参加した4名がそれぞれ印象に残ったセッションの感想を書かせて頂きます。

島田

Open SKT: メルペイ開発の裏側

speakerdeck.com

4階層アーキテクチャによる基本的な構成の説明から、高い信頼性を求められる決済サービスでどういった観点を重要視して、そのためにどう仕組みを作っているが興味深かった。決済システムの一貫性を保つための一般化したエラーハンドリングの考え方と、共通モデルのTry,Confirm,Cancelによる状態確保するための仕組みは参考になった。 また、メルカリとメルペイでの開発の考え方の違い。サービスの特性による求める安定基準に違いから来るものが興味深かった。特に開発フローでのレビューの差異等が参考になった。

RDBのトラブルの現場を追え!

speakerdeck.com

DBのトラブルとして考えられるケースの説明。全体を通してMySQL、PostgreSQLのそれぞれの勘所・差異の説明は興味深かった。 スロークエリのあるあるの対応や原因の切り分けには納得。不正データ(制約で守られていない)に関してはPostgreSQLとMySQL8から出来ること(チェック制約)が参考になりました。 ユーザー情報のテーブル設計に関しては普段感じている課題感に対してひとつ知見も得る事が出来て、面白かった。 最後の「 DBは同じ話が30年前からある」は、知見が陳腐化する速度がそこまで速くなく、どこでも利用する技術なので強みとなりやすいというのは、なんか良かった。

大石

ランチセッション「キーボードは好きですか?」

speakerdeck.com

私自身趣味で活動している自作キーボードに関するセッションをおいしいランチを食べなから聞くことができました。 このセッションでは最近ブームとなっている自作キーボードに関する内容でしたが、発表者がCorne Keyboardの設計者でもあり、大変濃い内容を聞くことができました。 また、発表資料が現在の自作キーボード文化をまとめた資料性の高い内容となっていますので、自作キーボードに興味のある方はぜひご覧ください。 弊社でも自作キーボードのもくもく会を定期開催していますので、この資料が役立つことと思います。

個人的に参考になった点

  • キーボードの種類(私は40%キーボード信者)
  • メカニカルスイッチの解説(Lubeに関する解説も良い)
  • メカニカルスイッチの構造、フランケンスイッチ(自分で作るのは大変なので触ってみたい)

コンパイラをつくってみよう

speakerdeck.com

「コンパイラをつくってみよう」というタイトルのとおり、発表者がライブコーディングでフルスクラッチのコンパイラを実装するという内容でした。 このコンパイラはGo言語で実装してアセンブリを出力するシンプルなものですが、ライブコーディングで少しずつソースコードの解析とコンパイラを実装する流れを見ることができました。 時々コンパイルエラーが発生するのですが、その際はギャラリーからエラー個所のアドバイスがあり、ギャラリー参加型のセッションという楽しい雰囲気となっていました。 この発表を聞いて自分でも簡単なコンパイラが作れそう、アセンブリ言語を扱うのも楽しそうという印象を受けました。

カンファレンス全体の感想

私がこれまで参加していた特定のプラットフォームの開発者のカンファレンスと異なり、ハードウェアやメーカー系の話題のあるカンファレンスで大変興味深く思いました。そして、まだまだ自分の知らない分野や勉強できることがあると感じましたので、機会があればまた参加したいと思います。 イベントの運営スタッフの方々、登壇者の方々、スポンサーの方々に感謝いたします。

田口

ブロックチェーン時代の認証

speakerdeck.com

ブロックチェーンについては正直ほとんど知らないことばかりだったのですが、興味本位で聞きに行きました。 自分のようにブロックチェーンについての知識が乏しい人にも詳しい説明がなされた発表で、大変助かりました。

現在のWebサービスは中央集権的であり、プライバシーやデータが提供される側で完全に管理されている状態で、ブロックチェーンの登場でそれが非中央集権的に、個と個のやり取りで管理されるようになってきているという話が印象的でした。現在のWebとブロックチェーンがお互いの課題感をお互いに解決できる未来を妄想するとわくわくしますね。発表者のrmanzokuさんもとても楽しそうに話していたのが印象的でした。

Web Componentsによる段階的AngularJS脱出作戦

docs.google.com

AngularJS、つまりAngularの1.x系のバージョンが2021年6月30日でEOLを迎えるので、今のうちから脱却に動いていこうという話でした。 弊社でもAngularJSで作られたプロダクトが動いているため、少しでも脱却するために得るものがあればと思い参加しました。

まず最初に、Web ComponentsがSafariでもサポートされていること、Polyfillまで見ればIE 11でもサポートされていることに驚きました。恥ずかしながら、もっと未来のことかと思ってました。 Web Componentsの仕様の一つであるCustom Elementsを使って、言葉通り段階的にAngularJSアプリケーションを書きかえていく話でした。 Angularでは公式でCustom Elementsをサポートしているパッケージ(@angular/elements)が出ており、アプリケーションの一部をCustom Elementsで書き換えるといったことが可能で、それを利用して少しずつAngularJSから脱却していくやり方を実際のデモを通して見れました。 このやり方は発表者であるlacolacoさん自身が考案し試行段階ということです。今後どうなっていくか気になるので、注視していこうと思います。

山下

現代フロントエンドに欠かせないwebpackとBabelを理解しよう!

speakerdeck.com

最近webpackerのバージョンアップをする機会があり、その際設定ファイル等の変更でbabelやwebpackのドキュメントを見ながら苦しんだため、是非聴きたいと思い聴いてきました。

前半はbabelやwebpackについて誕生の背景やコンセプトなどの説明、後半は内部実装を見ながら処理の流れのを追っていくという内容でした。 前半の説明がわかりやすく、個人的にはbabelがどのような流れでコードを変換し各処理にどのパッケージやプラグインが必要かを、変換されないパターンも交えながら解説してくれていて理解が深まりました。ただ、後半は内容が難しくまだまだ勉強が必要だと感じました。 また、今後babelやwebpackをどう学んでいけばよいかという質問に対して、公式ドキュメントを読みましょうという回答をされていました。babelやwebpackに限った話ではないですが、ついサボりがちなため公式ドキュメントを読み学んでいきたいと感じました。

ウォレットアプリ「Kyash」の先 〜「Kyash Direct」のアーキテクチャ〜

法人向けの決済プラットフォームKyash Directの開発についての内容でした。 既存Kyashのアーキがある中でスクラッチ開発を判断した経緯や、MicroservicesとMonolithどちらにするかをそれぞれメリット・デメリットを挙げどのように判断したかなど、開発を進める上で非常にためになる内容でした。 Microservicesでいくと決めた後も、サービスの分割方法、サービス同士の連携方法、DBの持ち方などについて、過去の経験や教訓、未来に起きるであろう課題の解決のしやすさを考慮しながら進めている点について見習わなければと感じました。 単に新しい技術を取り入れるだけでなく、自分たちのサービスや環境を考慮した設計をしていくことの重要性を感じた発表でした。

最後に

多種多様なセッションを聞く事ができ、buildersconのキャッチフレーズ「discover something new」とおり新たな知見を得ることが出来、大変有意義な時間となりました。 来年もまた参加とスポンサー等での協力が出来たらと考えています!