Deploy a React App using Webpack and AWS S3

Oct. 19, 2020, 2:43 p.m.

AWS Production React · 13 min read

Deploy a React App using Webpack and AWS S3

By Jaysha

Deploying a React App requires several packages to bundle the files and convert the code to JavaScript.

In this React tutorial, we will first bundle our React Chatbot with webpack and Babel. Then in a later section, we will deploy it to an AWS S3 bucket.

What is needed to bundle a React App?

  • a React app
  • install and configure webpack and webpack-cli
  • install and configure Babel
  • install and configure HTML webpack plugin
  • install and configure webpack development server

All of these packages are discussed in detail below.

 


 

Creating a React App

This tutorial assumes that you have already created and configured your React App using Facebook's create-react-app. However, any React app can be deployed using this method.

 


 

Webpack and webpack CLI

Webpack documentation

What is webpack?

Webpack is a JavaScript module bundler. Released in 2012, it is an open-source and designed for modern JavaScript applications.

Webpack bundles HTML, CSS, JS, and images, generating static assets representing these original modules. 

 

Why use webpack with React?

Webpack will bundle all the React components into condensed assets that are easily read by web browsers.

 

Install webpack and webpack-cli

Install webpack and webpack-cli - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm install webpack webpack-cli --save-dev

Install webpack and webpack-cli - macOS Terminal

User-Macbook:react-chatbot user$ npm i webpack webpack-cli --save-dev

Install webpack and webpack-cli in your app's directory. The install will take a few minutes.

 

Update the packages.json

react-chatbot > package.json

...
"scripts": {
    "start": "react-scripts start",
    "build": "webpack --mode production",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
...

Next, go to the file package.json and replace "build":"react-scripts build" with "build":"webpack --mode production", as seen above. 

 


 

Babel

Babel documentation

Now it's time to install Babel

 

What is Babel?

Babel is a JavaScript compiler that converts next-generation JavaScript code into browser-compatible Javascript. 

 

Why use Babel with React?

Babel will convert the React class components, ES6 variables, and JSX code to regular JavaScript so older browsers can render the component correctly. 

 

Install Babel

Install Babel and it's dependencies - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev

Install Babel and it's dependencies - macOS Terminal

User-Macbook:react-chatbot user$ npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev

We will install the babel-loader, the webpack loader for Babel, the babel/preset-env that complies JavaScript to ES5 and the babel/preset-react for compiling JSX to JS.

 

Create a new file called .babelrc

react-chatbot > (New File) .babelrc

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

After the installation, create file called .babelrc inside your app's directory. This is the same directory with package.json.

 

Create a new file called webpack.config.js

react-chatbot > (New File) webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};

Also, create another file called webpack.config.js. Again, create this file in the app's directory, the same folder as package.json.

The code above is a rile that states if a file ends in .js or .jsx, have the webpack send the code through the babel-loader.

 


 

Create the bundle

Now we can create the bundle.

 

Run the build command

npm run build - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm run build

npm run build - macOS Terminal

User-Macbook:react-chatbot user$ npm run build

Run the command npm run build, and the script "webpack --mode production" in the package.json file will run. 

The command prompt will then say that the asset main.js was created and webpack successfully compiled. 

 

View dist > main.js

react-chatbot > dist > main.js

/*! For license information please see main.js.LICENSE.txt */
(()=>{var e={669:(e,t,n)=>{e.exports=n(609)},592:(e,t,n)=>{"use strict";var r=n(867),o=n(26),i=n(372),a=n(327),l=n(97),u=n(109),s=n(985),c=n(61);e.exports=function(e){return new Promise((function(t,n){var f=e.data,p=e.headers;r.isFormData(f)&&delete ...(e.Component);t.render(e.createElement(j,null),document.getElementById("root"))})()})();

If you look at the file structure of the app, you will notice a new directory called dist with a file called main.js. The file main.js is the bundled version of the entire React app.

 


 

Adding the bundle to an HTML page

With the bundle created, let's load it into the HTML file. 

 

Install two more packages for webpack

Install html-webpack and html-loader - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm install html-webpack-plugin html-loader --save-dev

Install html-webpack and html-loader - macOS Terminal

User-Macbook:react-chatbot user$ npm install html-webpack-plugin html-loader --save-dev

Run the command npm install html-webpack-plugin html-loader --save-dev to install the html-webpack-plugin and the html-loader. 

 

Update the webpack.config.js file

react-chatbot >  webpack.config.js

const HtmlWebPackPlugin = require("html-webpack-plugin");

module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      },
      {
        test: /\.html$/,
        use: [
          {
            loader: "html-loader"
          }
        ]
      }
    ]
  },
  plugins: [
    new HtmlWebPackPlugin({
      template: "./public/index.html",
      filename: "./index.html"
    })
  ]
};

Then update the webpack.config.js file with a new const variable called HtmlWebPackPlugin that is called under plugins.

Also add another rule that states if a file ends in .html, have the webpack send the code through the html-loader.

If you used create-react-app to make your React app, the index.html is in the public folder. Link to the file with the line template:"./public/index.html", as seen in the example above. 

Else, if your index.html is in src directory, use template:"./src/index.html".

 

Run the build command again

npm run build - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm run build

npm run build - macOS Terminal

User-Macbook:react-chatbot user$ npm run build

Run the command npm run build again to bundle your index.html file and create the bundled asset in dist > index.html.

 

View the dist > index.html file

react-chatbot > dist > index.html

<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="%PUBLIC_URL%/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/><link rel="manifest" href="%PUBLIC_URL%/manifest.json"/><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script src="main.js"></script></body></html>

If you look at the new file called index.html in the dist folder, you will see it is a compiled version of the HTML code from public > index.html

 


 

Configuring a development sever with webpack

Our project is now bundled, so to avoid having to run npm build every time to push changes, install webpack-dev-server.

 

Install webpack-dev-server

Install webpack-dev-server - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm install webpack-dev-server --save-dev

Install webpack-dev-server - macOS Terminal

User-Macbook:react-chatbot user$ npm install webpack-dev-server --save-dev

Run npm install webpack-dev-server.

 

Update the packages.json

react-chatbot > package.json

...
"scripts": {
    "start": "webpack-dev-server --open --mode development",
    "build": "webpack --mode production",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
...

Next, update the package.json file with a new script for npm start.

 

Run the development server

Install webpack-dev-server - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm start

Install webpack-dev-server - macOS Terminal

User-Macbook:react-chatbot user$ npm start

Now when you run start the webpack development server will launch the bundled application version in the browser.

 


 

Deploying a React App to an AWS S3 bucket

AWS free tier

Now that our app is bundled, we can deploy the condensed files to an AWS S3 bucket.

 

What is required to deploy a React App to an S3 bucket?

  • create a free AWS account
  • create an S3 bucket
  • install and configure AWS CLI

 

Create an AWS account

Create a free AWS account at https://aws.amazon.com/free/

 

Give your username AWS S3 permissions with IAM

Before creating an S3 bucket, you need to give your user permission to AWS S3.

To give a user S3 permissions:

  1. Login to AWS
  2. On the AWS Management Console page find the IAM service (a) under the Security, Identify, & Compliance section of All Services or (b) by typing in IAM in the search bar
  3. Click on the IAM link
  4. Click the Users tab under the Access management section in the left side menu
  5. Click on the username you want to give access to
  6. Click the "Add permissions" button
  7. Select "Attach existing policies directly" and type in AmazonS3FullAccess
  8. Click the "Next:Review" button
  9. Check that the permission was added to the correct user on the Permissions summary page
  10. Click "Add permission" to save the changes

 

Create an S3 bucket for your React app

Now with the proper permissions added, you can create your S3 bucket.

AWS Simple Storage Service (S3) stores files and objects using a scalable storage infrastructure. S3 buckets act as containers for these files and can even be used to host a static website.

To create an S3 bucket:

  1. On the AWS Management Console page find the S3 service (a) under the Storage section of All Services or (b) by typing in S3 in the search bar
  2. Click on the S3 link
  3. Click on the "Create bucket" button on the right side of the screen

On the Create bucket page:

  1. Under General configuration:
    • name your bucket and section your region
  2. Under Bucket settings for Block Public Access:
    • deselect the" Block all public access" checkbox
    • select the warning box that states "Turing off block all public access might result in this bucket and the objects within becoming public"
  3. Keep the remaining default configurations the same
  4. Click the button "Create bucket" at the bottom of the page

S3 bucket for your react app

 

Update S3 bucket permissions

Now that we have our bucket, let's add read-only permission for anonymous users.

To add permissions:

  1. Click on your S3 bucket
  2. Select the "Permissions" tab
  3. Click on the "Bucket Policy" button
  4. In the Bucket policy editor add the following code, replacing "Resource" with the name of your bucket
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "AllowPublicReadAccess",
                "Effect": "Allow",
                "Principal": "*",
                "Action": "s3:GetObject",
                "Resource": "arn:aws:s3:::name-of-your-bucket/*"
            }
        ]
    }
  5. Click the "Save" button when you are done.

 

Add CORS configurations

We will also add CORS configurations to the S3 bucket to allows cross-origin requests. 

To add CORS configurations:

  1. Click on your S3 bucket
  2. Select the "Permissions" tab
  3. Click on the "CORS configuration" button
  4. In the CORS configuration editor add the following code 
    <?xml version="1.0" encoding="UTF-8"?>
    <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <ExposeHeader>x-amz-meta-custom-header</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
    </CORSConfiguration>
    
    
  5. Click the "Save" button when you are done.

 

Install AWS CLI

The bucket is created and configured so we can now upload our React app bundle to the S3 bucket.

We will be uploading via the AWS Command Line Interface.

Please follow the AWS CLI installation instructions for your specific OS before continuing.

AWS CLI installation instructions

 

Check AWS CLI is installed

Install webpack-dev-server - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> aws --v
aws-cli/2.0.47 Python/3.7.4 Windows/10 botocore/2.0.0

Install webpack-dev-server - macOS Terminal

User-Macbook:react-chatbot user$ aws --v
aws-cli/2.0.47 Python/3.7.4 Darwin/18.7.0 botocore/2.0.0

Once the installation process is complete, go ahead and run the command aws --v to check the installation worked. 

 

Create a set of AWS access keys

When using the AWS CLI, you need to provide a set of AWS access keys so the CLI can properly connect to your AWS account.

To create a set of keys:

  1. Click on your username on the upper right-side
  2. Select My Security Credentials from the dropdown menu
  3. Click the "Create access key" button under the section Access keys for CLI, SDK, & API access
  4. Two access keys will appear in a popup menu
  5. Click the "Download .csv file" button and save the keys

You will need both of the keys saved in the file to configure the AWS CLI in the next step.

AWS Access keys

If you do happen to lose the access keys, just create another set. 

 

Configure the AWS CLI

Configure AWS CLI - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> aws configure
AWS Access Key ID:****************
AWS Secret Access Key:****************
Default region name [us-west-1]:
Default output format [None]:

Configure AWS CLI - macOS Terminal

User-Macbook:react-chatbot user$ aws configure
AWS Access Key ID:****************
AWS Secret Access Key:****************
Default region name [us-west-1]:
Default output format [None]:

In the command prompt of your project, run the command aws configure. Then enter your AWS access key and AWS secret key you created in the previous step.

You can then skip the remaining configuration section by clicking Enter for each one. 

 

Update the package.json file

react-chatbot > package.json

...
"scripts": {
    "start": "webpack-dev-server --open --mode development",
    "build": "webpack --mode production",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "deploy": "aws s3 sync dist/ s3://name-of-your-bucket"
  },
...

Go to package.json and add a new script for deployment: "deploy": "aws s3 sync webpack/dist/ s3://name-of-your-bucket".

Be sure to replace name-of-your-bucket with the correct bucket name and to save the file.

 

Deploy to AWS S3 bucket

Deploy to the S3 bucket - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm run build

C:\Users\Owner\desktop\react\react-chatbot> npm run deploy

Deploy to the S3 bucket - macOS Terminal

User-Macbook:react-chatbot user$ npm run build

User-Macbook:react-chatbot user$ npm run deploy

 

Return to your CLI and run npm run build to bundle any changes then npm run deploy to upload the bundle to your S3 bucket.

All of the files in the dist directory will upload to the S3 bucket. 

 

Make your S3 bucket a domain

To make your S3 a domain:

  1. Click on your bucket
  2. You should see the index.html, main.js, and main.js.LICENSE.txt files
  3. Select the "Properties" tabs
  4. Click the "Static website hosting" card
  5. Select the "use this bucket to host a website" button
  6. Type index.html as the "Index document" and "Error document"
  7. Click the "Save" button to finish

AWS static website hosting

If you check on the card again, you should notice a URL Endpoint.

Click this URL and your app will appear in a new browser tab.

 


 

Solving common errors that could occur

ERROR: 'MODULE_NOT_FOUND" webpack-dev-server

  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'C:\\Users\\Owner\\Desktop\\react\\react-chatbot\\node_modules\\webpack-dev-server\\bin\\webpack-dev-server.js'
  ]
}
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! react-tutorial@0.1.0 start: `webpack-dev-server --open --mode development`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the react-tutorial@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

If you get an error when running npm start after installing webpack-dev-server, you need to downgrade your the webpack-cli version. 

 

1. Update the package.json

react-chatbot > package.json

...
 },
  "devDependencies": {
    ...
    "webpack-cli": "^3.3.12",
    ...
  }
}

Change the "webpack-cli" version to "^3.3.12", a version of webpack-cli without the bug, in package.json.

Be sure to save the file. 

 

2. Reinstall webpack-cli

Install webpack-dev-server - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm install

Install webpack-dev-server - macOS Terminal

User-Macbook:react-chatbot user$ npm install

Then run npm install to install the version specified in package.json.

 

3. Run the development server again

Run the webpack development sever - Windows Command Prompt

C:\Users\Owner\desktop\react\react-chatbot> npm start

Install webpack development server - macOS Terminal

User-Macbook:react-chatbot user$ npm start

Now when you run npm start, the developer server should open.

 

ERROR: Failed to parse json; Unexpected token } in JSON

npm ERR! code EJSONPARSE
npm ERR! file C:\Users\Owner\Desktop\code\react\react-chatbot\package.json
npm ERR! JSON.parse Failed to parse json
npm ERR! JSON.parse Unexpected token } in JSON at position 662 while parsing near '...y-react-example",
npm ERR! JSON.parse   },

If you get this error while trying to run npm run build, make sure there is no comma at the end of the last script added.

 

ERROR: fatal error: An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation: The specified bucket does not exist

fatal error: An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation: The specified bucket does not exist
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! react-chatbot@0.1.0 deploy: `aws s3 sync dist/ s3://deploy-react-example`
npm ERR! Exit status 1

If this error occurs while trying to deploy to your S3 bucket, you probably spelled the bucket name wrong in package.json.




0
Subscribe now

Subscribe to stay current on our latest articles and promos





Post a Comment
Join the community

0 Comments