0

I am attempting to serve a create-react-app site to AWS Cloudfront after deploying to S3.

The index.html is still trying to get old main.xxxxx.js after deploy to S3. A default service-worker.js is used to cache site in browser.

if you reload the browser, app is loading correctly.

The conflict may occur between service-worker.js cache and cloudfront cache. server-worker doesn't get the newly uploaded main.xxx.js but instead old one while cloudfront has newly main.xxxxx.js after we invalidate existing files

Re-produce:

npm run build.

aws s3 sync ./build s3://$S3_BUCKET/frontend --delete --acl 'public-read'

aws cloudfront create-invalidation --distribution-id $CLOUDFRONT_ID --paths '/*'

aws s3 cp ./build/service-worker.js s3://$S3_BUCKET/frontend/service-worker.js --cache-control max-age=0

The cloudfront is set to Use Origin Cache Headers (will use file Cache-Control headers)

Expected Behavior: After new deployment with the steps mentioned, when we try to access app on first attempt, this should get the new main.xxxx.js file and load updated contents

Taher A. Ghaleb
  • 5,120
  • 5
  • 31
  • 44
Vinay Gode
  • 111
  • 4
  • Can try control + shift + R , may be it is getting loaded from browser cache or you can clear the history – Shiva Dec 02 '18 at 03:49
  • **if you reload the browser, app is loading correctly**, what is the expectation here? – Shiva Dec 02 '18 at 03:54
  • I would expect the first time the page loads to load correctly, but it does not. It requires me to reload the browser once to load the app correctly. – Vinay Gode Dec 03 '18 at 21:37
  • you are facing this issue after the cache invalidation in cloud front? In that case, browser would load from cache too. so try to clean up browser history or load it and control + shift + R should hit to server. – Shiva Dec 04 '18 at 06:18
  • I have overlooked at caching site using `server-worker` in browser. If you know the cache name you can simply call https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage/delete from anywhere you like in the worker... `caches.delete(/*name*/);` found here.. https://stackoverflow.com/questions/45467842/how-to-clear-cache-of-service-worker – Shiva Dec 04 '18 at 13:19

2 Answers2

0

It is happening because these things has been cached at the CloudFront CDN as well please try to invalidate them Follow these steps: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html

after doing it wait for some time and you will see that it start reading the new files , please let me if there is any issue while doing this . Thanks

Prabhat Singh
  • 891
  • 8
  • 17
0

It's not entirely clear from your question if the issue is the CloudFront cache or the browser cache. You write that when reloading the page the app is loading correctly, so I suspect the object's cache and not CloudFront.

Anyways, create-react-app builds artifacts that are easy to cache. Any file in the static folder can have long-term cache setting as they have unique names, i.e. file name changes when content changes.

However, files in the root build folder don't have unique names, e.g. index.html doesn't change between builds (same for the service worker file).

What we do is the following:

  1. Sync static folder with a long max-age cache-control

    aws s3 sync build/static/ s3://$S3_BUCKET/static/ --cache-control "max-age=604800"

  2. Sync root folder with short cache control

    aws s3 sync build/static/ s3://$S3_BUCKET/static/ --cache-control "max-age=600"

  3. (Optional) invalidate root resources

    aws cloudfront create-invalidation --distribution-id $DIST_ID --paths /index.html /service-worker.js /asset-manifest.json

For this to work, you must set CloudFront to use the origin cache settings, as well as make sure the minimum TTL is less or equal than the index/manifest cache settings.

Read here for more details on origin cache settings vs. CF cache settings https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html

Community
  • 1
  • 1
LiorH
  • 18,524
  • 17
  • 70
  • 98