⛓️

Amplify Studioを活用したフロントエンド開発の制約と誓約

2024/07/30に公開

はじめに

レバテックでオウンドメディアの開発を担当している本名です。

今回はAWS Amplify Studioを活用したフロントエンド開発を通して感じた制約と誓約についてお話しできればと思います。

※弊社がAmplify Studioを採用した背景は以下に載っていますので、ぜひご覧ください。
https://speakerdeck.com/leveragestech/aws-amplify-studioto-figmanolian-xi-niyorulpkai-fa-noxiao-lu-hua

話すこと

開発を通じて感じた下記4つについて話します。

  • Figmaデザインの制約
  • overrideの制約
  • 開発者間で実装方法の認識を統一するための誓約
  • 今後の課題

話さないこと

  • 今回は開発を通じて感じたことを話しますので、Amplify Studioの環境構築や操作方法の詳しい説明はしません。

Amplify Stuidoとは

簡単にサービスの説明をすると、AWS Amplify Studioは、視覚的な開発環境を提供し、フロントエンドアプリケーションの迅速な開発を支援するサービスです。Figmaと統合してデザインをインポートし、コンポーネント生成やバックエンドサービス(認証、データストレージ、APIなど)とのシームレスな連携を実現します。これにより、デザイナーと開発者が効率的に協力してフルスタックアプリケーションを構築できます。

https://aws.amazon.com/jp/blogs/news/aws-amplify-studio-figma-to-fullstack-react-app-with-minimal-programming/

弊社では、デザインをインポートしてコンポーネントを生成し、シームレスな連携する部分を開発に取り入れていています。

Figmaデザインの制約

こちらは冒頭で話しましたが、デザインをインポートする際に必要なFigmaでのデザインの作り方についての話です。主に以下の点です。

  • Auto Layoutを可能な限り必ず適用する

これをしないとデザインをインポートした際のスタイルが全てabsoluteな配置になってしまいます。

デザインの組み方についての詳細は省略しますが、導入段階ではAWS Amplify UI KitというAuto Layoutで組んであるデザインサンプルがあるので、デザイン知識がなくても気軽に試せると思います。

overrideの制約

自作のFigmaデザインから生成されたコンポーネントが必ずしもFigma通りに生成されないことがあります。その場合は、ローカルでコンポーネントのスタイルをoverrideしてデザインを再現する必要があります。
具体的には以下の点です。

  • border-*
    • 生成後はborderにスタイルが変わってしまう。
  • text-stroke
    • 生成時にtext-strokeのスタイル自体がなくなってしまう。
  • etc

スタイル以外にも改行が表現できないためoverrideする必要があります。
実際のコードと合わせて説明します。

以下の生成されたコンポーネントファイルでは、childrenにある文字列内の改行コードが
になっており、改行されない状態になっています。
コメントにもある通り、生成コンポーネントを直接編集することはできないので、コンポーネント利用時に改行する必要があります。

生成されたコンポーネントファイル(jsx)
/***************************************************************************
 * The contents of this file were generated with Amplify Studio.           *
 * Please refrain from making any modifications to this file.              *
 * Any changes to this file will be overwritten when running amplify pull. *
 **************************************************************************/

/* eslint-disable */
import * as React from "react";
import { getOverrideProps } from "./utils";
import { Flex, Text } from "@aws-amplify/ui-react";
export default function Pc100Strength02(props) {
  const {
    overrides,
    ...rest
  } = props;
  return (
    <Flex
      (省略)
      {...getOverrideProps(overrides, "Pc100Strength02")}
      {...rest}
    >
        <Text
          fontFamily="Noto Sans JP"
          fontSize="36px"
          fontWeight="700"
          color="rgba(28,90,93,1)"
          lineHeight="50.39999771118164px"
          textAlign="center"
          display="block"
          direction="column"
          justifyContent="unset"
          width="unset"
          height="unset"
          gap="unset"
          alignItems="unset"
          top="52px"
          left="0px"
          padding="0px 0px 0px 0px"
          whiteSpace="pre-wrap"
          children="技術理解が深く専門性の高い&#xA;コンサルタントが質の高いマッチングを実現"
          {...getOverrideProps(
            overrides,
            "\u6280\u8853\u7406\u89E3\u304C\u6DF1\u304F\u5C02\u9580\u6027\u306E\u9AD8\u3044 \u30B3\u30F3\u30B5\u30EB\u30BF\u30F3\u30C8\u304C\u8CEA\u306E\u9AD8\u3044\u30DE\u30C3\u30C1\u30F3\u30B0\u3092\u5B9F\u73FE"
          )}
        ></Text>
    </Flex>
  );
}

1つのコンポーネントファイルに対して、1つのTypescriptの型定義がセットで生成されます。

TypeScriptで利用できる型定義
/***************************************************************************
 * The contents of this file were generated with Amplify Studio.           *
 * Please refrain from making any modifications to this file.              *
 * Any changes to this file will be overwritten when running amplify pull. *
 **************************************************************************/

import * as React from "react";
import { FlexProps, IconProps, ImageProps, TextProps, ViewProps } from "@aws-amplify/ui-react";
export declare type EscapeHatchProps = {
    [elementHierarchy: string]: Record<string, unknown>;
} | null;
export declare type VariantValues = {
    [key: string]: string;
};
export declare type Variant = {
    variantValues: VariantValues;
    overrides: EscapeHatchProps;
};
export declare type PrimitiveOverrideProps<T> = Partial<T> & React.DOMAttributes<HTMLDivElement>;
export declare type Pc100Strength02OverridesProps = {
    Pc100Strength02?: PrimitiveOverrideProps<FlexProps>;
    "\u6280\u8853\u7406\u89E3\u304C\u6DF1\u304F\u5C02\u9580\u6027\u306E\u9AD8\u3044 \u30B3\u30F3\u30B5\u30EB\u30BF\u30F3\u30C8\u304C\u8CEA\u306E\u9AD8\u3044\u30DE\u30C3\u30C1\u30F3\u30B0\u3092\u5B9F\u73FE"?: PrimitiveOverrideProps<TextProps>;
} & EscapeHatchProps;
export declare type Pc100Strength02Props = React.PropsWithChildren<Partial<FlexProps> & {
    overrides?: Pc100Strength02OverridesProps | undefined | null;
}>;
export default function Pc100Strength02(props: Pc100Strength02Props): React.ReactElement;

overrideして修正する場合は、以下のようにして改行タグを入れて改行をさせます。
(overrideについての詳しい解説はこちら)

<Pc100Strength02
overrides={{
  "技術理解が深く専門性の高い コンサルタントが質の高いマッチングを実現": {
    children: (
      <>
        技術理解が深く専門性の高い
        <br />
        コンサルタントが質の高いマッチングを実現
      </>
    ),
  },
}}
/>

このほかにも動的UI(アコーディオンやカルーセルなど)の動きの部分などAmplify Studioでの実現が難しいので、そういった箇所はslot機能を使ってローカルで別途UIを実装することもあります。

開発者間で実装方針の統一誓約

Amplify Studioを活用した弊社の開発体制は、1つのデザインチームに対して、開発チームが複数ある状態になっています。

こんな感じ

この状態で起きるのが、開発者または開発チームごとの実装方法の違いによるデザイン修正が多発してしまうことです。また、それによってデザインチームでもどのようにデザインを組むのが正しいのかわからないといった混乱の声もありました。

せっかくスタイルがある程度出来上がった状態のコンポーネント生成による開発リードタイムの改善が望めそうなのに、デザイナーとのコミュニケーションコストが上がってしまい、むしろ改悪に向かってしまいます…

そこで開発チーム間で共通の実装方針ルールを固めるようにしようとしています。
各チームで実装方法の足並みを揃えるために、実装方法をドキュメントに記載し、実装方法にずれが生じないようにします。

最低限スタイルのoverrideする箇所や動的箇所の実装方法は足並みを揃えたいですね。

今後の課題

今後の課題は主に以下になるかと考えています。

  • スタイルをoverrideさせるフローをできるだけ無くしていく
    • ここを整えられれば、デザイン修正や開発者・開発チーム間での実装差異は限りなくゼロに近づいていくと思ってます。
    • デザインの組み方で調整できるかAmplify Studioのアップデートで改善していくのかまだまだ改善の余地はありそうです。
  • 実装方法などのドキュメントを明示的に残していく
    • ここまで話した制約の通り、Amplify Studioならではの少し特殊な作業は属人性を生みやすいですが、これを許容しながら進めるためにも新規参画者でもわかりやすいようなドキュメントの構築が必要です。
    • ただドキュメントは形骸化しがちなので、メンテナンス含めてどう進めていくかは検討中です。
  • デザインチーム・開発チーム間での連携強化
    • デザイン・実装ルールに昇華したものを共有する機会
      • 複数チームで開発を行うので、ルールに昇華したものを各チームで認知できるような体制を作っていきたいと考えています。
      • 認知不足で余計な実装やコミュニケーションコストが発生するのを避けたい。

おわりに

余談ですが、Amplify Studioを活用した開発は、まだまだ制約が多いという印象から、パッと思いついたネタ的要素としてHUNTER×HUNTERの「制約と誓約」でしたw(本文ではあまり絡めて話せませんでしたが…)

何かリスクを背負うことで、代わりに利益を得ることが出来る。

ということで課題と向き合いながらエンペラータイム(開発リードタイム削減)を長くできるようしていきたいです。

レバテック開発部

Discussion