Material UIでFont Awesomeをラップする


はじめに

今回はMaterial UIを使ってFont Awesomeをラップすることがありましたのでその手順を残したいと思います。

検証環境

  • Material UI: 5.0.4
  • Font Awesome: 6.1.1

なぜMaterial UIを使ってFont Awesomeをラップするのか

Material UIは色やフォントサイズなどのテーマを定義したファイルを用意することで、個別に色やフォントサイズを指定しなくてもスタイルを適用することができます。

例えば、下記のように記述することで別ファイルに記載したprimary.mainの色を文字に指定することができます。

 <Typography  color={'primary.main'}>サンプル</Typography>

しかし、これができるのはMaterial UIが提供しているコンポーネントだけです。

Font Awesomeでアイコンに色を指定したい場合は下記のように書く必要があります。

const PrimaryMainColor = "#0C6993"
<FontAwesomeIcon icon={faHome} color={PrimaryMainColor} />

もちろんこのような手法でスタイルを指定することはできますが、Font Awesomeを含めた各パッケージごとにスタイルを指定すると管理がどんどん複雑になります。

そこでFontAwesomeもMaterial UIと同様の方法でスタイルを指定することができれば、スタイルの管理をシンプルにすることができると考えました。

コンポーネントの作成

下記の様に記述することでMaterial UIと同様の方法でスタイルを適用することができます。

下記では、Propsとしてmainlightdarkを指定できるようにしています。

また、それ以外のPropsはFontAwesomeIconを使うときと全く同じように指定することができます。

import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { styled } from '@mui/system';
import * as React from 'react';
import type { FontAwesomeIconProps } from '@fortawesome/react-fontawesome';

type colorType = 'main' | 'light' | 'dark';

type Props = Omit<FontAwesomeIconProps, 'color'> & {
  color?: color;
};

const Icon = styled(FontAwesomeIcon, {
  shouldForwardProp: (prop) => prop !== 'color',
  name: 'Icon',
  overridesResolver: (
    props: { color: colorType },
    styles
  ) => [
    props.color === 'main' && styles.main,
    props.color === 'light' && styles.light,
    props.color === 'dark' && styles.dark,
  ],
})<Props>({});

export const StyledIcon: React.FC<Props> = ({
  color,
  icon,
  ...inputProps
}) => <Icon color={color} icon={icon} {...inputProps} />;

theme.tsの作成

続いて、theme.tsを編集していきます。

components配下に今回作成したSyledIconのスタイルを設定することによってMaterial UIのデザインシステムを使ってFont Awesomeのアイコンのスタイルを変更することができます。

ここではアイコンの色としてmainlightdarkに各色を指定しています。

import { createTheme } from '@mui/material';
import type { Theme, ThemeOptions } from '@mui/material';

export const theme: Theme = createTheme({
  components: {
    StyledIcon: {
      styleOverrides: {
        main: {
          color:  '#0C6993',
        },
        light: {
          color: '#5097C4',
        },
        dark: {
          color: '#01579B',
        },
      },
    },
  },
} as ThemeOptions);

アイコンを利用するコンポーネント

アイコンを利用するコンポーネントでは、下記のように記述することでFontAwesomeのアイコンをMaterialUIのコンポーネントのように利用することができます。

  <StyledIcon icon={icon} color={'main'} />

まとめ

今回は、Material UIのデザインシステムでFont Awesomeのスタイルを変更する手法をまとめてみました。

本手法を用いることでFontAwesomeのアイコンのスタイルをMaterial UIと同様に管理することができますので、ぜひ一度検討してみたはいかがでしょうか。

serverless frameworkでサーバーレスアプリケーションを爆速で開発してみた

はじめに

AWSサービスであるlambdaやamazon api gatewayを素早くデプロイし開発を爆速で開始するためにserverless frameworkを使ってみました。

本記事では、serverless frameworkの導入手順についてまとめていきたいと思います。

想定読者

  • serverless frameworkに興味がある方
  • serverless frameworkを使ったサーバーレスアプリケーションのデプロイ方法を実際に手を動かしながら確認したい方

検証環境

  • aws-cli : 2.2.22
  • nvm 0.39.1
  • nodejs : v14.19.0
  • serveless framework : 2.72.2

事前準備

今回は、serverless frameworkを使ってaws環境上にlambdaとamazon api gatewayを作成します。そのためにいくつか設定が必要ですので順を追って設定していきます。

aws-cliのインストール

serverless frameworkでサーバーレスアプリケーションを作成するためにはaws-cliの設定が必要です。

まずは、aws-cliをインストールしましょう。

curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg"

インストールできているか確認してみます。バージョンが出てきたらインストール成功です。

aws --version
aws-cli/2.2.22 Python/3.8.8 Darwin/20.6.0 exe/x86_64 prompt/off

続いて下記のコマンドを使ってaws-cliを使うにあたっての認証情報を設定していきましょう。

aws configure

下記の項目を聞かれるので認証情報を設定していきましょう。認証情報を持っていない場合は、aws consoleにログインし、アカウントから払い出すことができます。

AWS Access Key ID: 
AWS Secret Access Key]: 
Default region name: 
Default output format [json]: 

nvm(nodejs)のインストール

続いて、nvmをインストールします。nvm(node version manager)はnodejsのバージョン管理ツールです。 nvmを使うことで複数のnodejsを切り替えて使うことができます。

nvmのHPにインストール方法が乗っているので、こちらの通りにインストールしていきます。

まずは下記のコマンドでインストールしていきましょう。

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

nvmをインストールする際~/.bash_profile~/.zshrc~/.profile~/.bashrcなどの設定ファイルに下記の記述が追記されています。

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm

インストールが成功しているかを確認してみましょう。 下記のようにバージョンが出力されればインストールが成功しています。

nvm -v
0.39.1

nvm: command not foundと出力される場合は、ターミナルを立ち上げ直すかsource ~/.bashrcsource ~/.zshrcのコマンドを実行してnvmのパスを通しましょう。

再びnvm -vで確認してみましょう。バージョン情報が出力されると思います。

バージョンが確認できたら、node.jsをインストールしていきます。

nvm install 14

nvm listと入力してみましょう。現在適用されているバージョン情報が確認できたらインストール成功です。

nvm list
->     v14.19.0

serverless frameworkのインストール

さて本題のserverless frameworkのインストールを行います。

インストールの場所は下記の2通りあります。

今回はグローバル環境にインストールしていきたいと思います。

下記のコマンドでインストールします。

yarn global add serverless

インストールが成功したかを確認してみましょう。下記のようにバージョン情報が出力されれば成功しています。 

Framework Core: 2.72.2
Plugin: 5.5.4
SDK: 4.3.0
Components: 3.18.2

サービスの作成

serverless frameworkではサービスという呼ばれる単位でシステムを作成します。

serverless frameworkはいくつかのテンプレートを用意してくれています。

今回は下記のコマンドで使ってaws、nodejs、typescriptを使ったサービスを作成していきましょう。

sls create --template aws-nodejs-typescript --name sample-service --path sample-service

下記のようなファイル群が作成されます。

|- sample-service
|   |- src
|   |   |- functions
|   |   |   |- hello
|   |   |   |   |- handler.ts
|   |   |   |   |- index.ts
|   |   |   |   |- mock.json
|   |   |   |   |- schema.ts
|   |   |   |- index.ts
|   |   |   |- lib
|   |   |   |   |- apiGateway.ts
|   |   |   |   |- handlerResolver.ts
|   |   |   |   |- lambda.ts
|   |   |   |- .npmignore
|   |   |   |- .nvmrc
|   |   |   |- package.json
|   |   |   |- README.md
|   |   |   |- serverless.ts
|   |   |   |- tsconfig.json
|   |   |   |- tsconfig.paths.json

ここで大事なのは下記のファイルです。

  • serverless.yml

少し中身を見てみましょう。

import type { AWS } from '@serverless/typescript';

import hello from '@functions/hello';

const serverlessConfiguration: AWS = {
  service: 'sample-service',
  frameworkVersion: '2',
  plugins: ['serverless-esbuild'],
  provider: {
    name: 'aws',
    runtime: 'nodejs14.x',
    apiGateway: {
      minimumCompressionSize: 1024,
      shouldStartNameWithService: true,
    },
    environment: {
      AWS_NODEJS_CONNECTION_REUSE_ENABLED: '1',
      NODE_OPTIONS: '--enable-source-maps --stack-trace-limit=1000',
    },
    lambdaHashingVersion: '20201221',
  },
  // import the function via paths
  functions: { hello },
  package: { individually: true },
  custom: {
    esbuild: {
      bundle: true,
      minify: false,
      sourcemap: true,
      exclude: ['aws-sdk'],
      target: 'node14',
      define: { 'require.resolve': undefined },
      platform: 'node',
      concurrency: 10,
    },
  },
};

module.exports = serverlessConfiguration;

大事な要素だけをピックアップしてまとめていきます。

  • plugins

適応したいプラグインを記述します。 serverless frameworkは基本的な機能のみを提供しており、各サービスに合わせてここにプラグイン記述することで機能を拡張していきます。 代表的なプラグインは後述するserverless-offlineなどがあります。。

  • provider

サーバーレスアプリケーションを作成したいクラウドプロバイダーを記述します。今回はテンプレートを使ってサービスを作成したのでawsが指定されています。

  • functions

クラウド環境上にデプロイする関数名を記述します。テンプレートではhelloが指定されていますが、serverless framework cliで作成したファイル群のfunctions/以下を見てください。テンプレートではhelloというディレクトリが存在し、中身をみるとソースコードが記述されています。serverless frameworkではfunctions以下に配置されたディレクトリ単位でlambdaを作成していきます。

  • custom/esbuild

テンプレートではコンパイラとバンドラにesbuildを使います。esbuildはwebpackと比較して高速に実行することができます。

デプロイの準備

デプロイをするための準備をしていきましょう。

テンプレートそのままでもデプロイすることが可能ですが、東京リージョンにリソースをデプロイをするために下記の記述を加えましょう。

※ regionにap-northeast-1(東京リージョン)を指定しない場合は、us-east-1(アメリバージニア北部)にデプロイされます。

provider {
 name: "aws",
 runtime: "nodejs14.x",
 region: "ap-northeast-1", // <- 追加
  ...
}

続いて、nodeのバージョンをディレクトリにある.nvmrcで指定されたバージョンに合わせるために下記のコマンドを実行します。

nvm use

nodeのバージョンが14系に指定されていることを確認しましょう。

テンプレートで指定されているバージョンはlts/fermiumのため2022/2/16時点ではv14.19.0が設定されるはずです。

また、package.jsonに記載されているライブラリをディレクトリ内にインストールします。

yarn install

warning は出力されますが、一旦無視して先に進みましょう。

デプロイ

アプリケーションのデプロイをしていきましょう。

クラウド環境にリソース群をデプロイするために下記のコマンドをターミナル上から実行しましょう。

sls deploy

serverless frameworkではプロバイダーにawsを指定した場合、cloud formationが裏で起動し、s3にcloud formationの設定ファイルをアップロードしたりアプリケーションをzip化するログが出力されます。

下記のようなログが出力されればデプロイが完了です。

Serverless: Running "serverless" installed locally (in service node_modules)
Serverless: Compiling to node14 bundle with esbuild...
Serverless: Compiling with concurrency: 10
Serverless: Compiling completed.
(node:89866) [DEP0147] DeprecationWarning: In future versions of Node.js, fs.rmdir(path, { recursive: true }) will be removed. Use fs.rm(path, { recursive: true }) instead
(Use `node --trace-deprecation ...` to show where the warning was created)
Serverless: Zip function: hello - 13.34 KB [43 ms]
Serverless: Packaging service...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
........
Serverless: Stack create finished...
Serverless: Ensuring that deployment bucket exists
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service hello.zip file to S3 (13.66 kB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
....................................
Serverless: Stack update finished...
Service Information
service: sample-service
stage: dev
region: ap-northeast-1
stack: sample-service-dev
resources: 13
api keys:
  None
endpoints:
  POST - https:/xxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello
functions:
  hello: sample-service-dev-hello
layers:
  None

curlで出力されたendpointを叩いてみましょう。

 curl -X POST -H "Content-Type: application/json" -d '{"name":"hoge"}' https:/xxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/hello

下記のようなログが出力されればデプロイは成功しています。

{"message":"Hello hoge, welcome to the exciting Serverless world!","event":{"resource":"/hello",".........}

ローカル環境での実行方法

続いてローカル環境でアプリケーションを動かしてみましょう。

アプリケーションの開発中に都度クラウド環境にデプロイして動作確認をするのは面倒ですよね。

serverless frameworkには様々なプラグインが用意されていて、その中でもローカル環境で動かすためのプラグインも用意されています。

プラグイン名はserverless-offlineです。

早速インストールしていきましょう。

yarn add -D serverless-offline

次にインストールしたプラグインをserverless frameworkに適用します。

serverless.ymlの中にプラグインを記載する項目があるので、記載しましょう。

const serverlessConfiguration: AWS = {
  ...
  plugins: ["serverless-esbuild", "serverless-offline"],
  ...
}

こちらでローカル環境でアプリケーションを動かすための準備は終わりました。

ローカル環境でアプリケーションを実行しましょう。

sls offline start

起動が成功すると下記の記述が現れます。

 POST | http://localhost:3000/dev/hello

別途ターミナルを立ち上げ、curlを使って叩いてみましょう。

 curl -X POST -H "Content-Type: application/json" -d '{"name":"hoge"}' localhost:3000/dev/hello 

下記のメッセージが表示されたらローカル環境での実行の成功です。

{"message":"Hello undefined, welcome to the exciting Serverless world!"}

serveless-offlineはアプリケーションを変更した際、自動でその変更を反映してくれます。

試しにアプリケーションコードを変更してみましょう。

sample-service/functions/hello/handler.tsを見てください。

 return formatJSONResponse({
    message: `Hello ${event.body.name}, welcome to the exciting Serverless world!!`,
  });

こちらのコードを下記のように変更してみます。

 return formatJSONResponse({
    message: `Hello Serverless world!!`,
  });

ファイルを保存して、再びcurlを実行してみましょう。

{"message":"Hello Serverless world!!"}  

レスポンスが変わっていることを確認することができます。

これで爆速でアプリケーションを開発することができますね。

サービスの削除

最後にサービスの削除をしましょう。

下記のコマンドでサービスを削除することができます。

slsl remove

下記のログが出力されたら削除が成功です。

Serverless: Running "serverless" installed locally (in service node_modules)
Serverless: Getting all objects in S3 bucket...
Serverless: Removing objects in S3 bucket...
Serverless: Removing Stack...
Serverless: Checking Stack delete progress...
.........................
Serverless: Stack delete finished...

Serverless: Stack delete finished...

まとめ

今回は、serverless frameworkを使ってサーバーレスアプリケーションを開発するまでの流れをまとめてみました。

serverless frameworkを使うことで従来より簡単にサーバーレスアプリケーション開発環境を整えることができます。

個人開発でも会社の開発でもservereless frameworkを使ってみることを検討してみてはいかがでしょうか。