Deploying ReactJS (w/ webpack) to S3 & CloudFront - reactjs

I have a ReactJS application that produces a dist folder when I perform an npm build. This can be uploaded to Amazon's S3 and everything is fine.
I'm looking to continuously deploy this application, so my thoughts were to deploy to s3://RANDOM_STRING/, producing:
RANDOM_STRING/js
RANDOM_STRING/css
RANDOM_STRING/index.html
I can't tell S3, to the best of my knowledge, to use a sub-directory as a web-root, so I looked into CloudFront and updating the origin to the directory. This takes a lot of time to update and actually can't be done through the aws-cli, so continuous deployment would be ruined.
I've looked at using file-loader to rewrite my url() calls to include the RANDOM_STRING into the deployment assets, but this feels pretty "ugly"
Does anyone have experience of this kind of deployment and could help me out?

Have you tried setting your Default Root Object? You can configure it to be a sub directory.
See here: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/DefaultRootObject.html

Related

Having trouble correctly building/deploying create-react-app using NPM

I've recently tried getting into the whole Node ecosystem and am trying to set up some continuous deployment for my app to AWS Amplify.
For background, my project structure looks like this:
project
public
index.html
src
App.tsx/App.js
package.json
As far as I know, this is basically what create-react-app gave me to start with, and I didn't change the file structure.
For most of my time working on the app, I've been able to go to the base project directory and use
npm start
to launch the app. This will bring me to the App.tsx/js homepage.
However, when I hosted this to AWS Amplify via GitHub, the default build settings actually point to the public directory, so the published site is actually point to index.html (which is basically just an empty placeholder).
While debugging, I ran
npm build
in my root project directory, which constructed a build folder, so now the overall project looks like this:
project
build
index.html
public
index.html
src
App.tsx/App.js
package.json
Now, running
npm start
will bring me to the index.html from the build directory, instead of App.js/tsx as it used to.
The AWS setup says that it will run
npm build
so I assume that what I've done on my local machine is mirroring what the AWS server is doing behind the scenes and explains why AWS is serving the empty index.html.
I've read a few articles and watched some videos about hosting a create-react-app on AWS, and in every version, it looks like AWS will serve the App.tsx/App.js right out of the box, rather than build/index.html, and I've not been able to find a good guide on how to configure this behavior. Quite frankly, there is an overwhelming number of similar-but-slightly-different answers for questions like this, which use different combinations of package managers, packages, hosting services, all on different release versions, with different setups, and it's very difficult for me to tell which ones apply to my scenario.
So I'm hoping someone can help straighten some of this out for me, or point me towards a good resource for learning more about this type of thing. Particularly interested in learning the right way to do these things, rather than a quick hack around whatever my particular issue is.
Some specific questions...
Is deploying things from a /build folder standard convention?
Why does create-react-app create a separate /src/app.tsx and /public/index.html that seem to be competing with one another as the app's "homepage"?
Why does the behavior of
npm start
change depending on whether
npm build
has been run?
Is the correct fix here to just insert my App.tsx component into the index.html? This doesn't seem hard, but doesn't seem right either
I have seen a lot of answers discussing tweaks to webpack.config.js to solve issues like this one. My project does have webpack installed, but as best I can tell, there is no webpack.config.js anywhere. Am I expected to create this file, or should it exist already? In either case, in which directory is it supposed to live? I've seen a couple answers saying it should be in /node_modules/webpack/, but also some saying it needs to live in the same directory as package.json
Things I've tried already: Spent a bunch of time reading through other StackOverflows and watching a few videos, but as outlined above, I'm finding it difficult to tell which could apply to my situation and which are unrelated, given the huge number of unique combinations of build/packages/platforms/versions. Also spent some time monkeying around with file structure/moving code around, but not very productively.
Eventually found my issue. In the production built version of my app (aka, /build), the bundled script created by webpack was failing in the browser because exports was undefined, so index.html was being served in its vanilla state, rather than with the TSX/JSX content. I changed the "module" property in tsconfig.json from commonjs to es6 and this fixed most of the problems.
Also of note is that the reason I couldn't find my webpack.config.js is that I had hidden ALL js files in my project, so VSCode wasn't finding it. I swapped to the suggestion from this blogpost to hide only js files with a matching TS file.
For general learning about how create-react-app works, I eventually found this page, which I found helpful:
https://blog.logrocket.com/getting-started-with-create-react-app-d93147444a27/
For the basic create-react-app
npm start
Is a short command for react-scripts start that sets up the development environment and starts your development server usually localhost:3000
npm build
After you are done developing, this command short for react-scripts build correctly bundles your app for production and optimizes the build for the best performance.
The files generated in the build folder are solely the files you serve to the public folder accessible by the public URL.
In short the files in the build folder should be copied to the public folder
AWS Amplify
Provides a CI/CD process where you don't have to set all this up by yourself, as long as you have a well-configured package.json file.
There are so many methods to deploy your react app to a production server but using AWS Amplify this link might help you out: https://youtu.be/kKwyKQ8Jxd8
More on create-react-app deployment: https://create-react-app.dev/docs/deployment/

How to deploy react application in a sub-directory using AWS Load Balancer

I have been trying to run my react application on a subdirectory .
I am using a load balancer (ALB) to and redirecting my application on "directory" from "https://mydomain/directory".
But static file of the build was not being found by my application
added direcctory on package.json. "homepage": "/directory"
added basename on react-router-dom
in my networks index.html is looking for ".#####/directory/static/js" and css in the same way
i am only able to run my react build by redirecting static request to my react build, but this is not the good solution because i want to run 3 applications on my ALB and this will cause me change my assets folder name manually in the build, obviously don't want to do that.
I have been applying multiple solutions but couldn't find a proper solution please someone help in this.๐Ÿ˜‘
ALB doesn't do redirects, and it doesn't do any sort of request path rewriting, it simply forwards the request to the target. You need to setup your server so it is actually serving the website from that folder, in other words change your assets folder name in the build.
If you don't want to do that, you would need to look at other AWS solutions like CloudFront which can proxy the request to a different path on the origin server.
I had a scenario of publishing react app with nginx inside docker with ci/cd. It took me setup a separate express server to serve app files and resolved the issue. Here is the repository synopsis of server.js that might help:
https://github.com/mkhizerali/store-pwa/blob/master/express/index.js

React-snap build fails unless build folder is uploaded to server

I'm using ReactJS and need some help with the build.
I am hosting a static site on a dedicated server.. in order to process that site I currently run my build locally and upload the 'build' folder to the server.
I've recently decided I should probably generate some static files for SEO (and adsense approval) and therefore I've added react-snap.
I run npm run build from my directory, and react-snap runs postbuild as expected however it fails unless I upload the build to the server first and then run the same build again to generate the static files (and then have to upload these again to the server for the static content to be available for search engine crawling).
I'm obviously missing a fundamental step in my build process here. I already want to refine it to a Git and push that to the server but I don't think this will help my react-snap problem.
Can anyone help?
Answering my own question for anyone with this problem...
My production variable for homepage was set specifically to the domain.. this is not required and does not allow for local crawling of the site. Explanation here:
https://github.com/stereobooster/react-snap/issues/153

Chrome keeps loading source map even after GENERATE_SOURCEMAP=false

I've built an app with CRA and I'm trying to prevent Chrome from loading source maps.
Here's what I've tried so far:
Build react app with the command GENERATE_SOURCEMAP=false react-scripts build.
Ensure that no .map files are present in /myprojectfolder/build/.
Delete all static files in my AWS S3 bucket.
Deploy build folder to S3 using aws s3 sync ./build s3://mybucket --profile=s3-admin.
Invalidate AWS Cloudfront using aws cloudfront create-invalidation --paths / /build /css/* /index.html /error.html /service-worker.js /manifest.json /favicon.ico.
Clear all browser cache at Chrome settings.
Hard refresh with โ‡งโŒ˜R.
But it's still showing the message Source Map detected with the exact code I wrote. Also tested on Windows Chrome with the same result. Safari seems to have stopped loading source maps, on the other hand.
Did I do anything wrong? Or is there anything else I can do (maybe reboot)?
Any advice would be appreciated. Thank you.
I had the same issue. In order to fix this, I tried removing/adding hosting multiple times. I noticed that one of the old s3 hosting buckets still has .map files. So I removed the obsolete buckets and verified the current bucket doesn't have js.map files. Now I no longer see the actual source .js files in dev. tools including individual .css files.

S3 Amazon Static Website with React?

I built a website using ReactJs, and to see the website, I generally do npm start and go to localhost:3000 via a browser.
I now want to host this website on S3, but without an EC2 instance. My understanding is that npm is a process, so it is server-side, and therefore, I would need to purchase compute to actually deploy my website.
I found this tutorial that does not mention paying for EC2 instance compute time: https://www.fullstackreact.com/articles/deploying-a-react-app-to-s3/
However, they still use NPM which makes me confused.
My question is: is it possible to use React if I were to only use Static S3 Website, without compute, and if so - how do I bypass NPM process?
React - component in seperate script does not work
In the above post, user tried to make a hello-world app in react, but all of the answers point them in the direction of making a server serve the content. I thought react is a front-end thing and can run without server-side processes. Is this true? Can someone explain why node.js is necessary or is paired with react, and whether is is possible to use react on s3 without ec2 compute?
It's possible to host a static react site entirely on s3. In this case, you would use node/npm only as build tools and to run your development server (localhost:3000).
npm would download your dependencies and you'd use node or gulp or webpack to build the assets into static files.
Then you would upload the files to s3 where it would serve the static files.
If you have some backend node code, then you would need to use ec2 or some other type of host. But if it's entirely static javascript, then there's no need for a node server.
Here are some links that might help explain in more detail:
https://medium.com/#omgwtfmarc/deploying-create-react-app-to-s3-or-cloudfront-48dae4ce0af
https://www.fullstackreact.com/articles/deploying-a-react-app-to-s3/
Try Gatsby! Here: https://www.gatsbyjs.org/
From the Github page: "Blazing fast static site generator for React"
Once you've generated your static pages, you can deploy on S3, Github pages...the choice is yours!
You can skip EC2 for your case. Here is why:
1) S3 Bucket + CloudFront (CDN) is really fast for static files serving. The React minified app is a group of static files which works best here. For the build of those minified files, I recommend using a CI/CD process or build them locally and just upload them to S3.
2) EC2 requires more work to setup, it consumes resources, it is not necessary for static files or React (unless you are using ReactDOMServer for dynamic content serving), and Node.js is not recommended for static files (Node.js get's blocked since it is single threaded so it is a best practice to keep static files away from it).
Here is a good article on the topic using Angular as an example: https://www.quora.com/Should-I-use-AWS-EC2-to-host-an-Angular-web-app-or-AWS-S3

Resources