Building and Deploying a Single-Page Application on AWS

Creating AWS resources will incur charges if the configurations are not within the free-tier limits. Always check the AWS pricing before creating any AWS resources.

Introduction

In this tutorial, you'll learn how to create a modern single-page application (SPA) using React and Vite, and deploy it to AWS using S3 and CloudFront. Specifically, we'll set up a React project with TypeScript, configure unit tests with Vitest, add npm scripts for operational tasks, and host the static site using AWS S3 and CloudFront for CDN capabilities.

By the end of this tutorial, you will have a fully functional SPA hosted on AWS, and you'll be able to build, test, and deploy React applications efficiently using modern tools and AWS services.

Getting Started

What Is a Single-Page Application?

A single-page application (SPA) is a web application that dynamically rewrites the current page rather than loading entire new pages from a server. This approach provides a more fluid user experience, similar to that of a desktop application.

What Technologies Will We Be Using?

We'll be using the following technologies/tools in this tutorial:

  • React: A JavaScript library for building user interfaces.
  • Vite: A fast build tool and development server for modern web projects.
  • TypeScript: A typed superset of JavaScript that compiles to plain JavaScript.
  • Vitest: A blazing-fast unit testing framework powered by Vite.
  • AWS S3: Amazon Simple Storage Service for storing and retrieving any amount of data.
  • AWS CloudFront: A fast content delivery network (CDN) service that securely delivers data, videos, applications, and APIs to customers globally.

Prerequisites

Before you begin, make sure you have the following:

  • An AWS Account: Sign up for a free AWS account if you don't have one.
  • Node.js and npm Installed: Ensure you have Node.js (v14 or later) and npm installed on your machine.
  • Basic Knowledge of React and TypeScript: Familiarity with React components and TypeScript syntax.
  • AWS CLI Installed and Configured: Set up the AWS Command Line Interface with your credentials.

Steps

We'll follow these steps to build and deploy our application:

  1. Initialize the React Project with Vite: Set up a new React project using Vite with TypeScript support.
  2. Set Up Unit Tests with Vitest: Configure Vitest for testing our React components.
  3. Add npm Scripts for Operational Tasks: Streamline tasks like building, testing, and deploying.
  4. Host the Static Site on AWS S3: Upload and configure our site on Amazon S3.
  5. Configure AWS CloudFront as a CDN: Set up CloudFront to deliver our content globally.

Important: Creating AWS resources will incur charges if the configurations are not within the free-tier limits. Always check the AWS pricing before creating any AWS resources.


Step 1: Initialize the React Project with Vite

In this step, we'll create a new React application using Vite and set up TypeScript support.

Instructions:

  1. Create a New Vite Project

    • Open your terminal and run the following command:

      bash
      Loading...
      • This command initializes a new Vite project named my-spa using the React TypeScript template.
      • Replace my-spa with your desired project name.
  2. Install Dependencies

    • Navigate to the project directory and install the required packages:

      bash
      Loading...
  3. Start the Development Server

    • Run the development server:

      bash
      Loading...
    • Open your browser and navigate to http://localhost:5173 to see the default React application running.


Step 2: Set Up Unit Tests with Vitest

We'll configure Vitest to enable unit testing for our React components.

Instructions:

  1. Install Vitest and Testing Libraries

    • Install Vitest and related packages:

      bash
      Loading...
  2. Configure Vitest in vite.config.ts

    • Open vite.config.ts and modify it to include Vitest configuration:

      typescript
      Loading...
  3. Create a Test Setup File

    • Create a new file at src/setupTests.ts and add:

      typescript
      Loading...
  4. Write a Sample Test

    • Create src/App.test.tsx with the following content:

      typescript
      Loading...
      • This test checks for the presence of the "Vite + React" text in the rendered App component.
  5. Update npm Scripts

    • In package.json, add a test script:

      json
      Loading...
  6. Run the Tests

    • Execute:

      bash
      Loading...
    • You should see the test results in your terminal.


Step 3: Add npm Scripts for Operational Tasks

We'll add scripts to automate common tasks like deploying the application to AWS.

Instructions:

  1. Add Deploy Script

    • In the scripts section of package.json, add a deploy script:

      json
      Loading...
      • Replace YOUR_BUCKET_NAME with the name of your S3 bucket.
      • Explanation: The command aws s3 sync dist/ s3://YOUR_BUCKET_NAME --delete synchronizes the contents of your local dist/ directory (the build output) with the specified S3 bucket. The --delete flag ensures that files not present in dist/ are removed from the bucket, keeping it in sync with your local build.

Step 4: Host the Static Site on AWS S3

We'll create an S3 bucket and configure it for static website hosting without making it publicly accessible.

Instructions:

  1. Create an S3 Bucket

    • Run the following command to create a new S3 bucket:

      bash
      Loading...
      • Replace YOUR_BUCKET_NAME with a globally unique name and YOUR_REGION with your AWS region (e.g., us-east-1).
  2. Build the Application

    • Build your project:

      bash
      Loading...
  3. Deploy to S3

    • Run the deploy script:

      bash
      Loading...
    • This command uploads your build files to the S3 bucket.

  4. Configure S3 Bucket for CloudFront Access

    • We will configure the bucket policy to allow CloudFront to access the bucket contents securely.

Step 5: Configure AWS CloudFront as a CDN

We'll set up CloudFront to deliver our content globally and securely access the S3 bucket using AWS CLI commands.

Instructions:

  1. Create an Origin Access Control (OAC)

    • CloudFront uses an Origin Access Control to securely access the S3 bucket.

    • Create an OAC:

      bash
      Loading...
      • Note the Id of the created OAC from the output.
  2. Create a CloudFront Distribution

    • Create a JSON file named distribution-config.json with the following content (replace placeholders with your values):

      json
      Loading...
      • Replace YOUR_BUCKET_NAME with your actual bucket name.
      • Replace YOUR_OAC_ID with the Id of the Origin Access Control you created earlier.
      • Adjust the CallerReference as needed to ensure uniqueness.
    • Create the CloudFront distribution:

      bash
      Loading...
      • Note the Id and DomainName of the created distribution.
  3. Update S3 Bucket Policy

    • Create a bucket policy JSON file named bucket-policy.json:

      json
      Loading...
      • Replace YOUR_BUCKET_NAME, YOUR_ACCOUNT_ID, and YOUR_DISTRIBUTION_ID with your actual values.
    • Apply the bucket policy:

      bash
      Loading...
  4. Test Your CloudFront Distribution

    • Wait for the distribution status to become Deployed. This may take several minutes.

    • Access your website using the CloudFront domain name provided (e.g., d1234abcdefg.cloudfront.net).

  5. Invalidate Cache After Deployment

    • Add an invalidate script to package.json:

      json
      Loading...
      • Replace YOUR_DISTRIBUTION_ID with your CloudFront distribution ID.
    • Run the script after deployments to ensure users receive the latest content:

      bash
      Loading...

Conclusion

Congratulations! You've successfully built a modern React single-page application with TypeScript, set up unit testing with Vitest, and deployed it to AWS using S3 and CloudFront. You now know how to set up a React project with Vite, write unit tests, and host your application on AWS for global access.

Customizing the Project

You can further enhance this project by:

  • Adding More Features: Implement additional components or integrate with APIs.
  • Setting Up Continuous Deployment: Use CI/CD pipelines for automatic deployments.
  • Enhancing Performance: Optimize your app using code-splitting and lazy loading.

Next Steps

To continue learning:

  • Explore Advanced Vite Features: Learn about plugins and custom configurations.
  • Dive Deeper into AWS Services: Look into AWS Amplify or AWS Lambda for serverless functions.
  • Improve Testing: Add integration and end-to-end tests using tools like Cypress.

Reference

Here's a summary of the commands and code used throughout this tutorial for your convenience.

Commands and Code Snippets

bash
Loading...

Additional Resources


Remember to always check the AWS pricing and free-tier limits to avoid unexpected charges.