Slide 1

Slide 1 text

© 2012-2021 BASE, Inc. 1 BASE Tech Talk #1 〜Next.jsを使ったカート大規模リプレイスPJの裏側〜 大木 聡(@roothybrid7) リプレースPJの全体像と技術選定 1

Slide 2

Slide 2 text

© 2012-2021 BASE, Inc. 2 自己紹介 2 大木 聡 :@roothybrid7 ● BASE, Inc. Product Dev Division > Tech Lead ● BASE入社直後は、iOSアプリ開発に従事しており、 今はこのカートPJのフロントエンド開発などに従事

Slide 3

Slide 3 text

© 2012-2021 BASE, Inc. 3 今回の話 ● 購入フローの短縮 ● 追加購入導線の設置 ● 購入商品のSNSシェアを促す https://baseu.jp/22660 先日、カートをリニューアルしました。 3

Slide 4

Slide 4 text

© 2012-2021 BASE, Inc. 4 なぜリプレースしたのか?

Slide 5

Slide 5 text

© 2012-2021 BASE, Inc. 5 なぜリプレースしたのか? 限界だったから 機能の拡張性やメンテナンス性といった点で 5

Slide 6

Slide 6 text

© 2012-2021 BASE, Inc. 6 従来のアーキテクチャ(モノリシック) ● コードベースの肥大化 ● 見えない依存関係がいくつも生まれる ● 段々アプリケーションが複雑化 最初は、素早くリリースできて良かった が。。。どんどん機能が詰め込まれていった。 ● 市場価値の検証 ● 利益を生み出せる最小限のもの カート機能を含む1つのアプリケーション 6 CakePHP 2 UI Business Logic Data Access Cart Author/Copyright holder: Henrik Kniberg. Copyright terms and licence: All rights reserved

Slide 7

Slide 7 text

© 2012-2021 BASE, Inc. 7 モノリスから機能を剥がす 7 UI CakePHP 2 Data Access Business Logic CakePHP 4 Next カート機能を切り離して、新システムを構築 UI Business Logic Data Access Cart Frontend Backend OpenAPI

Slide 8

Slide 8 text

© 2012-2021 BASE, Inc. 8 モノリスから機能を剥がす 8 1 2 3 旧システムへは機能追加停止 新システムへ切り離す フロントエンドも分離

Slide 9

Slide 9 text

© 2012-2021 BASE, Inc. 9 モノリスから機能を剥がす 新旧2つのシステム両方に実装するコストが高いため、意図的に機能追加されないようにし てもらっていた。 リリースに2年弱かかったため、開始されなかったプロジェクトがいくつかある。 ただし、重要度やインパクトの大きな機能に関しては、追加コストを払って両方に実装。 9 旧システムへは機能追加停止

Slide 10

Slide 10 text

© 2012-2021 BASE, Inc. 10 モノリスから機能を剥がす UI CakePHP 2 Data Access Business Logic CakePHP 4 Next カート機能を切り離して、新システムを構築 UI Business Logic Data Access Cart Frontend Backend OpenAPI 新システムへ切り離す 機能を別システムに切り離すことにより、コンテキストが明確になり、実装のしがらみが減 り、変更が用意になる。 変更や問題特定の容易さ > 実装難易度、実装量増大

Slide 11

Slide 11 text

© 2012-2021 BASE, Inc. 11 モノリスから機能を剥がす フロントエンドアプリケーションとして、独立 してビルド、デプロイをすることが可能に。 バックエンドからプレゼンテーション層を分離 UI Data Access Business Logic CakePHP 4 Next Frontend Backend OpenAPI APIを介してのみデータの参照・更新が可 能 -> UIの制御にBusiness Logicの混入、不 用意なデータアクセスがなくなる

Slide 12

Slide 12 text

© 2012-2021 BASE, Inc. 12 フロントエンド構成

Slide 13

Slide 13 text

© 2012-2021 BASE, Inc. 13 フロントエンドCI・デプロイ周り Developer Push GitHub Actions Unit Testing/ Linting cart locales Push GitHub Actions POEditor Editor 翻訳テキスト編集 Pull& Push Merge Publish npm GitHub packages 開発時のフロー

Slide 14

Slide 14 text

© 2012-2021 BASE, Inc. 14 フロントエンドCI・デプロイ周り Deployer 手動実行 GitHub Actions cart GitHub packages デプロイフロー ECS Deploy Build 最新のLocale パッケージ取得 最新のLocale パッケージイン ストール

Slide 15

Slide 15 text

© 2012-2021 BASE, Inc. 15 フロントエンド構成 UIの描画と振る舞いの定義、バックエンドとのリソースのやりとり + ページの配信(SSR) Backend Server Backend for Frontend(BFF) Browser フロントエンドでのみ利用する データを保存 API API SSR/API

Slide 16

Slide 16 text

© 2012-2021 BASE, Inc. 16 Next.js採用してよかった点 1 2 3 全部JavaScript/TypeScriptで実装でき、ページの配信も簡単 > PHP/JSでViewが分断とかPHPの変数をJSへ埋め込むとかがない ビルドやBundleのための環境構築を一から作らなくても良い > 難しいWebpackの設定やJS Bundleの作成・埋め込みを自分でやらなくて良い (Great defaults for production) VercelやGoogleの研究成果をいち早く利用できる > Web技術の叡智が詰まったReactコンポーネントのリリース (Building on powerful React abstractions) ※Great defaults for productionやBuilding on powerful React abstractionsは、Next Conf 2021 Keynoteでの言葉

Slide 17

Slide 17 text

© 2012-2021 BASE, Inc. 17 Next.js採用してよかった点 3 VercelやGoogleの研究成果をいち早く利用できる > Web技術の叡智が詰まったReactコンポーネントのリリース (Building on powerful React abstractions) HTML Tag React Component 内容 prefetchやClient-sideでの遷移 自動リサイズ、ローディング中のblur表示 ローディング戦略設定やパフォーマンス改善

Slide 18

Slide 18 text

© 2012-2021 BASE, Inc. 18 Next.js Server Side Rendering ● 閲覧メインではなく、更新処理が多くあり、購入ごとに内容が異なる ○ Static Site Generationで生成できるものがほとんどない ● API Tokenなどの保存・復元は、ブラウザ側ではなくサーバ側で行う ○ JavaScriptで、Cookieに保存し、 document.cookie経由で取得してほしくない ● 販売不可状態やメンテナンス状態を事前に検出 ○ 販売不可な場合に、レンダリングするのは無駄なので別ページへリダイレクトするなど

Slide 19

Slide 19 text

© 2012-2021 BASE, Inc. 19 Next.js その他 ● パフォーマンス改善などバージョンアップ時の恩恵を受けられるように対応 a. Nextの機能をなるべく利用 b. データレイヤーなど、狭義のWeb UI以外のロジックを他のテクノロジーで管理し、 React Componentsを薄く保ち、a. を行えるようにする ■ Open API, XState, Recoil

Slide 20

Slide 20 text

© 2012-2021 BASE, Inc. 20 Next.js その他 とはいえ、ReactコンポーネントがWebアプリ ケーション制御の中心になっていることが多 い。 そのため、Reactとその他ライブラリの間を繋 ぐGlueコードやReact Bindingsライブラリが 必要なこともある。 ● Recoilの状態同期 ● React NativeのNative API実行コンポーネ ント > Reactコンカレントモードサポート以降どう なるか Recoilの状態同期の処理コード

Slide 21

Slide 21 text

© 2012-2021 BASE, Inc. 21 Next.js その他 ● 国際化対応 ○ i18n Routing ■ v10からサポート ■ 言語検出とURLハンドリング ○ i18n Translation ■ 翻訳テキストの取得と適用 ■ 他のライブラリで賄う(next-translateなど) https://shop.thebase.in/shops/shop/checkout/edit https://shop.thebase.in/en/shops/shop/checkout/edit

Slide 22

Slide 22 text

© 2012-2021 BASE, Inc. 22 CSS ● styled-jsxを採用 ○ Reactコンポーネント毎にCSSを記述できれば十分 ○ 共通のスタイルはCSS Modulesを併用 ● PostCSSも併用 ○ 必要な機能を選んで組み合わせられる ○ CSSの学習コストのみでいい CSS Moduleでimport PostCSS 必要な機能を選ぶ

Slide 23

Slide 23 text

© 2012-2021 BASE, Inc. 23 CSS設計 ● RSCSSを採用 ● 3つの基本概念がありルールが少ない ○ Components ○ Elements ○ Variants ● ComponentsはReactコンポーネントと1:1に対応づけられる ● ElementsはComponents内部の要素のこと ● Variantsはクラス名をハイフンで始め、ComponentsやElementsのバリエーションを規 定する

Slide 24

Slide 24 text

© 2012-2021 BASE, Inc. 24 Storybookを使って汎用コンポーネント開発 ● アプリケーション上でコンポーネントを実装する場合、特定の状態にするのに骨が折れる ● Storybookだと、渡す引数を工夫すれば良いのでコンポーネント実装のみに集中できる

Slide 25

Slide 25 text

© 2012-2021 BASE, Inc. 25 フォーム周り ● 注文内容を更新するのに中心的な要素 ○ 複雑なバリデーションロジックを制御する必要がある ■ ✋禁則文字、全角カナ ● 制御するの難しい ○ input要素などの値は、文字情報として取得されてしまう(数値ならnumberで扱いたい) ■ 型付けされていない値 ○ 組み込みの機能は、ブラウザによって使える使えないがある ○ 大きなフォームのバリデーション実行制御難しい ■ いつの時点で実行する? 個別要素の制御は? 入力変更時? blur時? submit時?

Slide 26

Slide 26 text

© 2012-2021 BASE, Inc. 26 フォーム周り ● 要素の監視、値の検証と取得が簡単にできる ● いつから検証するか(change, blur, submit) の制御が可能 > 検証の実行タイミングの設定がどうあれ、 submit時にバリデーションを実行した時の ロジックだけを書けば良い ● バリデーションエラーの表示も簡単 ● 基本的なバリデーションルールも設定できる が、別の高度なバリデーションライブラリを 組み合わせることも可能 React Fook Form(フォームバリデーションライブラリ)

Slide 27

Slide 27 text

© 2012-2021 BASE, Inc. 27 フォーム周り ● ValidationSchemaを定義 ● React Hook Formと組み合わせて利用 ● 単独でも使用できる ○ 起動時に環境変数で渡した設定値の検証 ○ Express.jsで立てたAPIサーバのリクエス トパラメーターの検証 Superstruct

Slide 28

Slide 28 text

© 2012-2021 BASE, Inc. 28 フォーム周り ● 検証した値のデフォルト値を埋めたり、型の 変換ができる ○ input要素などは、基本文字列として値を 返すと思うが、要素の都合は全く興味ない ため、この機能を使って型変換している Superstructの機能(coercion)

Slide 29

Slide 29 text

© 2012-2021 BASE, Inc. 29 フォーム周り ● name属性を構造化することによって、 React Hook Formは、その構造通りの JavaScript Objectでフォームデータを管理 する ● input要素のブラウザ毎の差異などには立ち 入りたくないので、React Hook Formが管 理するデータに対してバリデーションをかけ たい ● React Hook Formの管理するデータ構造を もつValidationSchemaをSuperstructで定 義して利用 Superstruct フォームに対応する ValidationSchemaを定義

Slide 30

Slide 30 text

© 2012-2021 BASE, Inc. 30 フォームバリデーションの仕組み submit時に構造化されたJavaScript Objectとして取得 フィールド登録と 監視、値の反映と 取得 他のValidationライブラリで値の検証をするためのresolver 検証結果を React-hook-for mで扱える形式 へと変換 値の検証と データ変換 フィールド値と Schemaを渡す フィールド値と Schemaを受け取る 検証結果を返す React Hook Form Superstruct

Slide 31

Slide 31 text

© 2012-2021 BASE, Inc. 31 フォームバリデーションの仕組み ● SuperstructはResolverが用意されていた が、細かい部分は握り潰されていた。 ○ Superstructのカスタムルール未対応 ● React Hook Formのエラーメッセージは、 国際化対応できない Validation Resolverのカスタマイズ

Slide 32

Slide 32 text

© 2012-2021 BASE, Inc. 32 注文処理

Slide 33

Slide 33 text

© 2012-2021 BASE, Inc. 33 注文するには、他のシステムと協力が必要 ドメインモデリングして発見したモデルを元 に、フロントエンドへ公開するデータをリソー スとして定義。 注文セッションリソースがメインリソースで、 別のリソースはこれに紐づく。 バックエンドがリソースを管理しているが、 APIにアクセスするためのTokenと各リソース のIDをフロントエンドで保存しておく必要があ る。 OpenAPIを使ってAPIエンドポイントやリソースを定義 カートリソース 商品を管理 注文内容リソース 注文するための情 報を管理 注文セッションリソース カートに商品を追加して から注文完了するまでを 追跡するリソース Token APIにアクセス するための Token文字列。 注文セッション を生成した時に 一緒に返される

Slide 34

Slide 34 text

© 2012-2021 BASE, Inc. 34 注文するには、他のシステムと協力が必要 商品追加は、既存システムから転送 ショップ(既存システム) 商品ページ Cart Frontend カートページ Hyperlink カートに追加する 商品情報を転送 Cart Backend Cart API JSON API 商品情報の送信 作成したリソース やTokenの返却 新規追加 ショップ(既存システム) 商品ページ Cart Frontend カートページ カートに追加する 商品情報を転送 Cart Backend Cart API 商品情報の送信 更新リソースの返却 既存追加 既存リソースの取得と返却

Slide 35

Slide 35 text

© 2012-2021 BASE, Inc. 35 注文するには、他のシステムと協力が必要 作成した注文データは他システムでも利用可能なように互換性を保つ Cart Frontend カートページ Cart Backend Cart API 注文実行 各種リソースの更新 Business Logic/ Data Access 注文データ保存 ショップ管理(既存システム) 注文管理ページ 社内管理(既存システム) 管理ページ ショップオーナーが 注文を処理 カスタマーサポートが 注文内容を確認

Slide 36

Slide 36 text

© 2012-2021 BASE, Inc. 36 リソース取得・更新

Slide 37

Slide 37 text

© 2012-2021 BASE, Inc. 37 OpenAPI Spec/Generator OpenAPI定義から、仕様を参照した実装の強制や自動コード生成可能 バックエンドが別(Cart Backend) 仕様書作成(OpenAPI Spec) API Client自動生成 バックエンドが同一(Cart Frontend) OpenAPI Generator CLI 仕様書作成(OpenAPI Spec) API Client自動生成 OpenAPI Generator CLI API Server手動実装 express-openapi 仕様自体の機能拡張 仕様を参照した機能の追加&実装の強制 import

Slide 38

Slide 38 text

© 2012-2021 BASE, Inc. 38 OpenAPI Generator ● コード生成にgenerateコマンドは使っておらず、batchコマンドを使っている ○ 複数のAPI仕様書が存在するため ○ コマンドライン引数を、yamlかjsonファイルで設定ファイルとして定義可能 ○ 設定ファイルは他の設定ファイルをinclude可能 ○ 設定ファイルをワイルドカードで指定すると、複数のAPI Clientがまとめて生成可能 # 生成コマンド openapi-generator-cli batch *.yaml

Slide 39

Slide 39 text

© 2012-2021 BASE, Inc. 39 OpenAPI Client エラーレスポンス ● 正常レスポンス時の挙動と異なる ● エラーレスポンスが発生した場合、呼び出し側に丸投げされる(throw!!!) ● カートの場合、エラーレスポンスボディに、エラーコードをセットしているため困る 400 Bad Request { “errors”: [ { “code”: “shop_can_not_sell”, “sub_code”: “shop_is_not_public” } ] } エラーレスポンス例

Slide 40

Slide 40 text

© 2012-2021 BASE, Inc. 40 OpenAPI Generatorで生成したコードを拡張 (Middleware) ● Middlewareを使うと、リクエスト前後に処理を挟むことができる

Slide 41

Slide 41 text

© 2012-2021 BASE, Inc. 41 OpenAPI Generatorで生成したコードを拡張 ● Middlewareの処理でResponseオブジェクトを拡張 (Proxy API, Object.defineProperties) ○ メタプログラミングな様相だが仕方ない ○ RecoilのLoadableを真似たI/Fで、レスポンスボ ティを取得 ○ Responseオブジェクト自体にレスポンスボディを 保存し、後から取り出せるようにする

Slide 42

Slide 42 text

© 2012-2021 BASE, Inc. 42 OpenAPI Generatorで生成したコードを拡張 ● API呼び出しを関数でラップ ○ throwされたエラーレスポンスからレスポンスボ ディの取得 ○ カスタムエラーでラップ ■ カスタムエラーからエラー詳細情報を取り出せる ■ エラーオブジェクトの名前は、RFC 7807 - Problem Details for HTTP APIs から命名

Slide 43

Slide 43 text

© 2012-2021 BASE, Inc. 43 リソースのレンダリングと更新で要件が異なる 複数リソースを レンダリング リソース更新は、 一度に一つだけ

Slide 44

Slide 44 text

© 2012-2021 BASE, Inc. 44 リソースのレンダリングと更新で要件が異なる 複数リソースを レンダリング ● 複数の情報から総合的に判断する必要がある ○ カートに配送不要商品が入っている >配送先入力なし ○ テイクアウト商品が入っている >テイクアウトの受取日時を指定 ● 古くなった内容では適切な判断ができないので、情報 を適度に最新にする必要がある >時間経過やリソース更新失敗時にエラーコードを見 て情報を最新にする ● APIから取得した内容をそのまま描画するわけではな く、UIの表現に合わせて変換が必要 依存関係がある

Slide 45

Slide 45 text

© 2012-2021 BASE, Inc. 45 APIリソースの定期的な取得 ● データフェッチのためのReact Hooksライブラリ ● 面倒臭い非同期処理のハンドリングを隠蔽でき、 コードをシンプルに保てる ● propsやstateを参照するような使用感なので、宣 言的なViewであるReactと相性がいい ● optionsによって、取得タイミングを制御でき、定 期的にデータ取得可能(これもまた宣言的) ○ interval ○ ブラウザタブフォーカス時 ○ コンポーネントマウント時 SWR

Slide 46

Slide 46 text

© 2012-2021 BASE, Inc. 46 ● fetcherにOpenAPI Clientを使った呼び出 し関数を指定することで、Promise制御を勝 手にやってくれる ● keyをnullにすることで、データフェッチを 一時停止ことができる >必須のリクエストパラメーターが取得でき た場合のみリクエスト実行させることが可能 SWR const { data, error } = useSWR(key, fetcher) const { data } = useSWR( shouldFetch ? '/api/data' : null, fetcher) 条件付きフェッチ APIリソースの定期的な取得

Slide 47

Slide 47 text

© 2012-2021 BASE, Inc. 47 ● 取得したAPIリソースのデータ構造そのままレンダリングすることは少ない ○ 何らかの変換を行うことがある ○ 他のリソースを組み合わせ表示することもある >合計送料=商品数 x 基本送料 ● リソースの更新で、リクエストパラメータとして利用することもある >配送方法の更新バージョン(取得時点のスナップショット) SWRは簡単にAPIリソースを取得できて便利だが、リソースはユースケースに合わせて表現 を変える必要がある >別の解決策を模索する必要がある リソースはユースケース毎に表現を変える必要がある

Slide 48

Slide 48 text

© 2012-2021 BASE, Inc. 48 Recoil 状態管理ライブラリ ● 状態を共有でき、React Hooks(useStateな ど)と同じような使用感で利用可能 ● 余計なボイラープレートコードが不要 ● atomという単位で状態を分割管理 ● selector(純粋関数)によって、atomの内容 を受け取り変換させたり、atomの内容を更 新したりできる ○ 入力にはatomだけではなくselectorや他 のデータソース(DBやAPIなど)も接続可能 ○ 非同期関数にもできる ● atom effectsが強力 リソースはユースケース毎に表現を変える必要がある

Slide 49

Slide 49 text

© 2012-2021 BASE, Inc. 49 Recoil atom atom定義 利用する側 リソースはユースケース毎に表現を変える必要がある

Slide 50

Slide 50 text

© 2012-2021 BASE, Inc. 50 Recoil selector selector定義 利用する側 リソースはユースケース毎に表現を変える必要がある

Slide 51

Slide 51 text

© 2012-2021 BASE, Inc. 51 Recoil 非同期selector ● 非同期関数で定義できるため、APIリクエス トの結果をselectorの評価結果として返すこ とが可能 ● ただし、評価結果はkey毎にキャッシュさ れ、冪等性を担保する必要があるため、リク エストの度、変更されうるリソースを扱うの は向かない ● 例は、滅多に変わることのない郵便番号と住 所のマッピングをAPIで取得しキャッシュす る処理 Key=postalAddressQuery${code} で結果をキャッシュ リソースはユースケース毎に表現を変える必要がある

Slide 52

Slide 52 text

© 2012-2021 BASE, Inc. 52 Recoil atom effects ● atomの初期化や、副作用処理が書ける機能 ● DBやlocalStorageなど、外部のデータソー スを使って、atomの初期化や、状態の永続 化、同期が行える ● Pay IDに登録する際のパスワード管理に利用 するatomとatom effectsの例 リソースはユースケース毎に表現を変える必要がある

Slide 53

Slide 53 text

© 2012-2021 BASE, Inc. 53 SWRとRecoilを組み合わせる/Xstateから特定通知を受け取った場合も再検証 リソースはユースケース毎に表現を変える必要がある 53 React Component useSWR 強制再検証(mutate) リソース取得 useEffect(xstate.subscription) OpenAPI Client useSetRecoilState(recoil.selector) 通知受け取り登録 リソース更新通知 (カートリソース更新 など) Recoil リソース反映 リソース反映 選択項目表示 送料合計計算に提供 選択項目の詳細 情報を提供 リソース更新のため、 FormDataを送信 強制再検証

Slide 54

Slide 54 text

© 2012-2021 BASE, Inc. 54 リソースの更新は一度に一つだけだが。。。 ● あるリソースが更新されると、依存している他のリ ソースに、新たな制約が生まれることがある AmazonPay決済情報を反映する(一つのワークフロー) 1. AmazonPay決済情報(配送先、支払い情報)取得 2. 注文セッションリソースにAmazonPay決済情報を 反映(AmazonPayの配送先を変えてはならないとい う制約が生まれる) 3. 2.を通じて、1.が注文内容リソースへ反映可能かを 検証 4. 1.を注文内容リソースへ反映 次のステップへ進める前に新たな制約が生まれる リソース更新は、 一度に一つだけ

Slide 55

Slide 55 text

© 2012-2021 BASE, Inc. 55 XState StateMachine/StateCharts ● StateMachine及びStateChart ● StateChartは、抽象化及び階層化した状態 遷移モデルを定義する描画方式及び視覚言語 ● “こうあるべき”というアプリケーションの動 作を、宣言的に記述できる ● XStateは、定義した状態遷移モデルを、イ ンスタンス化して、アプリケーションに組み 込んで利用することができる ● Recoilとの状態の考え方の違い ○ Recoil: atomやselectorで評価された値 ○ XState: 定義された概念(画像参照) リソース更新のためのワークフローを管理 https://stately.ai で作成したXState Machine

Slide 56

Slide 56 text

© 2012-2021 BASE, Inc. 56 状態遷移とイベント、それをトリガーに実行されるアクションやサービス リソース更新のためのワークフローを管理 状態: asleep, awake イベント: wakes up, falls asleep @xstate/inspect という開発ツールで 描画されたMachine ● 状態遷移やイベントなどあらゆる事象をトリガーにアクション関数を実行可能。 ○ ENTRY/〜, DO/〜 ○ XState外の世界ともやりとりができる(Next/React) ● 複雑なサービスロジック(Promise,Callback,Machine etc.)を組み込み実行可能。 ○ INVOKE/〜 リソース更新に利用

Slide 57

Slide 57 text

© 2012-2021 BASE, Inc. 57 AmazonPay 決済利用 ワークフロー XStateでワークフローを定義 idle SUBMIT_AMAZON_PAY_LINKING submitting.amazonPayLinking INVOKE / postAmazonPayLinking routingError ENTRY / dispatchRoutingError needsToRefreshForm draft defaultSetting INVOKE / setCheckoutDefaults done: postAmazonPayLinking [shouldBeSetDefaults] error: postAmazonPayLinking done: postAmazonPayLinking [hasDraft] done: postAmazonPayLinking [shouldBeSetFormData] DISPATCH_ERROR 以降省略 AmazonPayの紐付け 注文内容に住所コピー 注文内容の足りない 項目埋める 住所の項目不足(電話 番号など) 注文内容のその他項目 の入力必須 AmazonPayの紐付け失敗 得られたAmazonPayの SessionIdを送信 XStateの状態遷移やイベント、アクションを駆使して、アプリケーションを動作させるのは、React/Nextの役割 以降省略

Slide 58

Slide 58 text

© 2012-2021 BASE, Inc. 58 まとめ

Slide 59

Slide 59 text

© 2012-2021 BASE, Inc. 59 まとめ Great defaults for production!! Next.jsの枠組みの中で、ビルドやページ配信などWeb技術のあらゆることを 全部まかなってくれ、アプリケーション実装に集中できた。

Slide 60

Slide 60 text

© 2012-2021 BASE, Inc. 60 まとめ 1から新しく作ることができた 既存の仕組みに乗る必要がなかったので、SOLID原則に基づき、 拡張性、メンテナンス性の高いコードとは?と言うのを見つめ直すことができた。

Slide 61

Slide 61 text

© 2012-2021 BASE, Inc. 61 まとめ 移行してからが本番 リリースしてから、思ってもみなかった問題や改善提案などが上がってくるため、 どう改善していくかが今後の課題

Slide 62

Slide 62 text

© 2012-2021 BASE, Inc. 62 質問 ● カートに商品を入れたままアプリを閉じたとき/カートから商品を卸した時にどういう通 信、処理を行っているのだろうか ● ユーザー情報などグローバルで状態管理してる場合、どうやって永続化していますか。