buildしたReactページをS3にaws-cli s3 syncしようとして失敗した話
Reactで作ったページをbuildしてS3にあげて公開しようとしました。
/mypage
├─data/
│ ├─****.json
│ └─****.json
├─static/
│ ├─css/
│ └─js/
│ │ └─ main.21292925.jsなど
├─index.html
.
.
.
└─favicon.ico
ディレクトリ構成は上記のような作りで、/mypage/dataにReactページとは別にjsonファイルが置いてあり、それ以外static/以下がReactをbuildした時に生成されるファイルです。
これをローカルと同期させようとして
aws-cli s3 sync --size-only --delete /mypage s3://******/mypage/ --cache-control max-age=21600 #※ダメな例
のようにしたところ公開したところ、Reactページが真っ白になってしまいました。
このコマンドにした意図としてはdata/ディレクトリにあるjsonはファイル名が変わることがあり、また中身の変更がなくてもtimestampsが変更されることがあるので--size-onlyオプションを指定し、使用しなくなったjsonやReactページ内でも不要になったものを削除するように--deleteをつけていました。
しかし、Reactの場合buildするたびにstatic/js/main.*****.jsのファイル名が変わってしまいます。一方でindex.htmlは内部でimportするstatic/js/main.*****.jsだけ変わってファイルサイズはそのままになることがあります。このため、index.htmlは更新されずに、static/js/main.*****.jsだけが更新され(前回のファイルが削除され、ファイル名が変わったものがアップされる)結果的にindex.htmlがimportするstatic/js/main.*****.jsが存在しない状態になってしまいました。
ということで最終的に以下のようにしました。
aws-cli s3 sync --exclude /mypage/data/* --exact-timestamps /mypage s3://******/mypage/ --cache-control max-age=21600
aws-cli s3 sync --size-only --delete /mypage s3://******/mypage/ --cache-control max-age=21600
1度目のsyncでdataディレクトリを除いてtimestampの変更を見て更新します。これでindex.htmlは確実に更新されます。また、この時--deleteをつけていないので前回buildのstatic/js/main.*****.js等は残ってしまっています。
2度目のsyncでdataディレクトリが更新されます。また、--deleteオプションが付いているので前回buildのstatic/js/main.*****.js等は削除されます。
Discussion