以前、Lambda@Edgeを使って、静的サイトのサブディレクトリのアクセスをindex.htmlを参照する設定を書きましたが、 CloudFront Functionsを使えばLambda@Edgeがなくても実現できることを知りましたので共有します。 Lambda@EdgeよりもCloufFront Functionsのほうが良かったところは、なんと言っても関数の反映がめちゃくちゃ早いです! やりたいこと CloudFrontのサブディレクトリにアクセスが来たらindex.htmlを参照する URLに /index.html があれば、/index.html を取ったURLにリダイレクトさせる URLの末尾に「/」があれば取る(remove trailing slash) CloudFront 関数を作成 CloudFrontにアクセスして、左のメニューから 関数 を選んで、右上にある 関数を作成 ボタンをクリックします。 関数の名前を記入して 関数を作成 ボタンをクリックします。 関数を書き換えます 関数コード > 開発 からJavaScriptコードを下記のコードに書き換えます。 https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/example-function-add-index.html このサンプルを参考にしてますが、やりたいことの 1「CloudFrontのサブディレクトリにアクセスが来たらindex.htmlを参照する」 は実現できますが、 2「URLに /index.html があれば、/index.html を取ったURLにリダイレクトさせる」, 3「URLの末尾に「/」があれば取る(remove trailing slash)」 はできないので少しアレンジを加えてます。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

続きを読む

トレイリングスラッシュ とは、URLの末尾につく「 / 」のことです。 URLの末尾にスラッシュはいるんですかね?必要ないんですかね?? 今回は必要ないパターンで、URLの末尾に「 / 」があれば取ってしまうLambda@Edgeの設定方法を共有します。 条件 S3 + CloudFront で静的ホスティングしているWEBサイトの構成を前提に説明します。 手順 ここにその手順が載ってまして、これに沿って実行していきます。 https://serverlessrepo.aws.amazon.com/applications/arn:aws:serverlessrepo:us-east-1:951661612909:applications~LambdaEdgeRemoveTrailingSlash LambdaEdgeRemoveTrailingSlashの関数を作成する Lambda関数の作成 から Serverless Application Repositoryの参照 を選択します。 パブリックアプリケーション の検索窓から、「LambdaEdgeRemoveTrailingSlash」を検索します。 検索窓の下にある[カスタム IAM ロールまたはリソースポリシーを作成するアプリ]チェックボックスをONにすると、 LambdaEdgeRemoveTrailingSlash が出てくるのでクリックします。 次の画面の右下にある、「このアプリがカスタム IAM ロールを作成することを承認します」 にチェックを入れて、デプロイボタンを押します。 画面が変わりますので、一番下にあるリソースの中から論理IDの項目をクリックして関数を開きます。 関数をLambda@Edgeへデプロイする Lambda関数のページに遷移しますので、アクションメニューからLambda@Edegeへのデプロイをクリックします。 デプロイの設定をします。 URLの末尾のスラッシュを取りたいWEBサイトのCloudFrontディストリビューションIDを入力します。 CloudFrontイベント を ビューアーリクエスト にします。 最後の Lambda@Edgeへのデプロイを確認 に チェックを入れて デプロイをします。 デプロイが終わるとトリガーが追加されているとお見ます。 数分ぐらい経つと設定が反映されてると思いますので、末尾に「/」をつけてアクセスし、「/」が取れてリダイレクトされてたら成功です! もしできないよー!設定ちゃうで!ということがありましたら、コメントをお待ちしております。お疲れ様でした!

続きを読む

recoilとlocalStorageを使って状態の永続化をしたはいいけど、 localStorageのremoveItemをしたい時にどうすればいいか、 試してて多分これが正解かなーっと思いましたので共有します。 間違ってたらコメントくださいm(_ _)m localStorageEffect サンプル見るとnewValueが instanceofで DefaultValue ならremoveItem と書いてあります。 ここを通るようにすれば removeItem できました。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import { AtomEffect, DefaultValue } from "recoil"; export const localStorageEffect: <T>(key: string) => AtomEffect<T> = (key: string) => ({ setSelf, onSet }) => { if (typeof window !== "undefined") { const savedValue = localStorage.

続きを読む

WEBフォントをnpmでインストールできるFontsourceをwebpackでビルドする先にエラーが出たので webpack.config.js をどうかけば良いのかのメモです。 yakuhanjp は「約物半角専用のWEBフォント」で任天堂のホームページで使われてるフォントです。 1 $ yarn add @fontsource/yakuhanjp 1 import "@fontsource/yakuhanjp"; webpackでビルドする時、何も設定してなければ @font-face のところでエラーになります。 1 2 3 4 5 6 7 8 9 10 ERROR in ./node_modules/@fontsource/yakuhanjp/index.css 2:0 Module parse failed: Unexpected character '@' (2:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.

続きを読む

クリーンアーキテクチャって難しいですね。DDDとの違いもまだ良くわかってませんが、 その構成や思想に触れ、ええやん!と思ったので何とかフロントでも採用できないかなぁと思い、 色々調べてまとめましたので、晒してみようと思います。 参考サイト ▼ 実装クリーンアーキテクチャ https://qiita.com/nrslib/items/a5f902c4defc83bd46b8 ▼ フロントエンドでClean Architectureを適用してみる(+サンプルコード) https://qiita.com/ttiger55/items/50d88e9dbf3039d7ab66 ▼ Facebook製の新しいステート管理ライブラリ「Recoil」を最速で理解する https://blog.uhy.ooo/entry/2020-05-16/recoil-first-impression/ ファイル構成 SWR を使ってデータをfetchする場合は、こんなまどろっこしいことしなくても、 APIサーバーにClean Architectureを採用すれば問題ないと思いますが、 フロントが直接AWSやFirebaseなどからデータを読み書きするサーバーレスのような構成の場合は、 各ドメイン層は独立したinterfaceを持ち、疎結合になっていると便利かなと思いました。 また、Presentation層はReact Custom HookでUIに反映させてます。 呼び出すときに UseCase を引数に渡すことで、関係のない UseCase を実行しないようにしてます。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 domain/ ├── driver │ └── userDriver.ts ├── entity │ └── user.ts ├── interface │ ├── driver │ │ └── UserDriver.

続きを読む

Next.js, Gatsby.js, Nuxt.jsなどのStatic Site Generatorを使ったLPや、JAMStack構成でビルドされたファイルをS3にアップロードしてCloudFrontでキャッシュすることで、サーバーダウンなどを気にしないでページを運用したいなどあると思います。ただの1枚ページのHTMLだけならいいのですが、サブディレクトリにもHTMLファイルがある場合、どうすればいいのか。 https://example.cycloud.io/subdir/ このようなURLにアクセスすると、CloudFrontから Access Denied 403 のレスポンスが返ってきます。 https://example.cycloud.io/subdir/index.html こうすればアクセスできるのですが、ちょっとかっこ悪いですよね。 Lambda@Edge を使うとこの問題を解決できるので、その方法を紹介します。詳しいセキュリティの説明や、S3のバケット作成手順、CloudFrontのディストリビューションの作成手順は割愛させていただきます。 手順 リージョンを us-east-1 にする Lambda関数の新規作成 コードソースを書き換えてDeployする 新しいバージョンを発行 CloudFrontのトリガーを追加して設定する サブディレクトリのURLにアクセスして表示確認する 参考 リージョンをus-east-1にする 2021年5月時点では、後述する トリガーの選択でCloudFrontを選択できるのがus-east-1リージョンのみ となっているため、リージョンは 米国東部 (バージニア北部)us-east-1 を選択してください。 Lambda@Edge 関数を作成 AWS Lambdaのページから 関数の作成 ボタンを押して、Lambda関数の新規作成を一から作成します。関数名を記入して、ランタイムを Node.js にします。今回は新規から作る紹介なので、デフォルトの実行ロールの変更 は AWSポリシーテンプレートから新しいロールを作成 を選びます。ロール名を任意で入力し、 ポリシーテンプレートは「cloudfront」と検索 して、 基本的なLambda@Edgeのアクセス権限(CloudFrontトリガーの場合) を選択します。内容を確認して 関数の作成ボタンを押します。 コードソースを書き換えてDeployする コードソース?ソースコード?どっちかわかりませんが、ここではコードソースと書いてあるのでコードソースと書きます。 index.js を選択して、下記の内容に書き換えます。次に、 新しいバージョンを発行 をクリックします。 index.js 1 2 3 4 5

続きを読む

Invariant failed: You should not use <Link> outside a <Router>というエラー <Link to={path}> を含んでいるコンポーネントをStorybookに追加すると以下のようなエラーが出ます。 Invariant failed: You should not use <Link> outside a <Router> Error: Invariant failed: You should not use <Link> outside a <Router> at invariant (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:133623:11) at http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:124464:86 at updateContextConsumer (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:115964:19) at beginWork$1 (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:116347:14) at HTMLUnknownElement.callCallback (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:96456:14) at Object.invokeGuardedCallbackDev (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:96505:16) at invokeGuardedCallback (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:96560:31) at beginWork$$1 (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:121900:7) at performUnitOfWork (http://localhost:9009/vendors~main.1df07f438181fe4f3aec.bundle.js:120815:12) at workLoopSync (http://localhost:9009/vendors~main.1df07f438181f そこで役に立つのが、 storybook-react-router というモジュールです。 StorybookのDecoratorに追加するだけで、上記のエラーが解消されます。 https://www.npmjs.com/package/storybook-react-router

続きを読む

プロフィール画像

こたぽん

JavaScript, React, NextJS, VueJS, NuxtJS, AWS, Firebase, Git, ビールと生ハムが好き

Rakuten, Inc. CyberAgent, Inc.