Vite+React+Amplify initial setup!
Tags: typescript, react, vite, amplify
Published: 2022-10-12 11:34:03


## Purpose of this article.
 
**I want to try out the very fast build tool [Vite](https://ja.vitejs.dev/)!** 
I wanted to know how to start a project with my usual React+Amplify configuration.
This is my personal note.

## Software versions
The main software versions are listed below.

* node v18.9.0
* TypeScript 4.6.4
* Vite 3.1.0
* React 18.2.0

## Summary ahead of time
The official Amplify page guides how to use create-react-app when linking Amplify and React.
When using Vite, there are some parts that do not work as they are, so it is necessary to deal with errors.
This section outlines the errors and how to handle them. (Details are described below).

### `amplify pull` gives me an error

```
✖ There was an error initializing your environment.
Failed to pull the backend.
🛑 Must use import to load ES Module: /Users/xxxxxxxx/my_first_vite/src/aws-exports.js
require() of ES modules is not supported.
require() of /Users/xxxxxxxx/my_first_vite/src/aws-exports.js from /snapshot/repo/build/node_modules/amplify-frontend-javascript/lib/frontend-config-creator.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.

```

We need to treat this error like this.

* Rename aws-exports.js to aws-exports.ts
* Remove the line "type": "module" from package.json

**Additional Info.**
I got a message from Discord community, below!
> For what it's worth, the ESM issue (where we have to remove "type": "module") is fixed with the latest version version of the CLI, 10.2.3

### Error with `yarn dev`.
```
Uncaught ReferenceError: global is not defined
```
The following actions will be taken
Change index.html

### `amplify publish` causes error

```
2: import { ProviderError } from "@aws-sdk/property-provider";
3: import { Buffer } from "buffer";
4: import { request } from "http";
            ^
5: /**
6:  * @internal
error during build:
Error: 'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-node/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
```

Change vite.config.ts

## Development Procedure

Assuming that node, AmplifyCLI, and Vite have already been installed, we will start with project creation.

* Create a React project using Vite
* Create an Amplify project
* Initialize the app
* Do the data model integration
* Hosting with Amplify CLI

### Create a React project using Vite
The commands are as follows.

```zsh
yarn create vite my_first_vite --template react-ts
```

"my_first_vite" is the name of the project, and can be any value you wish.
--template react-ts applies the React TypeScript template.
Please also read the official website [[1]](https://vitejs.dev/guide/#scaffolding-your-first-vite-project), which explains this command.

### Creating an Amplify project
There are multiple ways to create an Amplify project, but here we will use AmplifyStudio.

#### Creating a project in the AWS Management Console
First, select AWS Amplify (hereafter referred to as Amplify) from the AWS Management Console and click
Select [New app]>[Build an app] from the upper right corner of the screen as shown below.

![Amplify Studio new app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ae9trmszcasvtchk4bn.png)

Next, enter the App name on the following screen and click "Confirm deployment".
In this case, the name is "my_first_vite", but you can use any name you like.


![Confirm deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zbzrrwlinh1lo2uf3y5y.png)

The figure below shows the waiting screen during deployment. （It takes 5 to 6 minutes.)


![now deploy is going.](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4t4cqet6wt3rv0n54x89.png)

When the screen transitions to the following, click "Launch Studio" to launch Amplify Studio.


![Now let's launch the studio](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/habdjl11f8hoj274zpwf.png)

#### What to do after launching Amplify Studio
Amplify Studio allows you to configure various backend resources.
It is not the purpose of this article to introduce them in detail, so we will only define a simple data model here.
Other things can be done, such as generating a UI in conjunction with Figma or using Cognito to incorporate authentication, but please refer to another article [[2]](https://qiita.com/akiraabe/items/55f28fe4f721f74eb992) or the AWS tutorial [[3]](https://aws.amazon.com/jp/blogs/news/aws-amplify-studio-figma-to-fullstack-react-app-with-minimal-programming/).

##### Defining the Data Model
Define the data model as follows. When you are done, press [Save and Deploy].


![Let's launch data model view](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zh4s6fwpygimleqzzz84.png)

This is the screen waiting to be deployed. This process will take some time because AppSync and DynamoDB will be created by CloudFormation at this time. (It may take about 10 minutes).


![deploy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wk8zf4ldg8upoa8repz5.png)

When a deployment is complete (successful), you will be taken to the following screen. (Press "Done" to close the screen.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o028wxlvud47t4zfprc8.png)



Here, (2) Update your app code will guide you through an example source code when you select the programming language, model, operation, etc. (This is a simplified version, so please refer to the document [[4]()] for details. (This is a simplified version, so you should check the documentation [[4]](https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js/) for details)

#### Pull Amplify materials locally

In the React project created by yarn create, run the amplify pull command as follows.
(Here we are working in the VSCode terminal)

An error will occur, but how to deal with it is described later.

```
 amplify pull
? Select the authentication method you want to use: AWS profile

For more information on AWS Profiles, see:
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html

? Please choose the profile you want to use default
? Which app are you working on? xxxxxxxxxxxxxx                              
Backend environment 'staging' found. Initializing...
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path:  src
? Distribution Directory Path: dist *** This is "build" by default, but we have explicitly changed it. ***
? Build Command:  npm run-script build
? Start Command: npm run-script start
✅ GraphQL schema compiled successfully.

Edit your schema at /Users/xxxxxxxx/my_first_vite/amplify/backend/api/myfirstvite/schema.graphql or place .graphql files in a directory at /Users/xxxxxxxx/my_first_vite/amplify/backend/api/myfirstvite/schema
Successfully generated models. Generated models can be found in /Users/xxxxxxxx/my_first_vite/src
? Do you plan on modifying this backend? Yes
⠙ Fetching updates to backend environment: staging from the cloud.✅ GraphQL schema compiled successfully.

Edit your schema at /Users/xxxxxxxx/my_first_vite/amplify/backend/api/myfirstvite/schema.graphql or place .graphql files in a directory at /Users/xxxxxxxx/my_first_vite/amplify/backend/api/myfirstvite/schema
✔ Successfully pulled backend environment staging from the cloud.
✖ There was an error initializing your environment.
Failed to pull the backend.
🛑 Must use import to load ES Module: /Users/xxxxxxxx/my_first_vite/src/aws-exports.js
require() of ES modules is not supported.
require() of /Users/xxxxxxxx/my_first_vite/src/aws-exports.js from /snapshot/repo/build/node_modules/amplify-frontend-javascript/lib/frontend-config-creator.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename aws-exports.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/xxxxxxxx/my_first_vite/package.json.

```

**An error occurs.** So, we will respond according to the message.

* Rename aws-exports.js to aws-exports.ts. (Note that aws-eports.js is created for each amplify pull, so you need to rename it for each pull.)
* Remove the line "type": "module" from package.json.

```diff:package.json
{
  "name": "my_first_vite",
  "private": true,
  "version": "0.0.0",
-  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.0.17",
    "@types/react-dom": "^18.0.6",
    "@vitejs/plugin-react": "^2.1.0",
    "typescript": "^4.6.4",
    "vite": "^3.1.0"
  }
}
```

After making the above modifications, rerun `amplify pull`.

### Set up the initial configuration of the app

At this point, we will launch the application once.

```zsh
## Install dependent modules
yarn install

# Start the development server
yarn dev
```
The application at this point looks like the following



![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7w1w5qpa1wa0hefktayv.png)


Change the application to use Amplify.

The file to be changed is as follows. (The project root is listed as the starting point)

* package.json
* src/index.css
* src/main.tsx
* src/App.tsx

Include a diff in package.json. (After making changes, run yarn install.)


package.json
```diff_json:package.json
{
  "dependencies": {
+    "@aws-amplify/ui-react": "^3.5.4",
+    "aws-amplify": "^4.3.36",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
}
```


Update index.css with the following

```css:index.css
@import url('https://fonts.googleapis.com/css2?family=Inter:slnt,wght@-10..0,100..900&display=swap');
body {
  margin: 0;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
    sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

code {
  font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
    monospace;
}

```

main.tsx below.

```diff_tsx:src/main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
+import { AmplifyProvider } from '@aws-amplify/ui-react';
+import { Amplify } from 'aws-amplify';
import App from './App'
import './index.css'
+import config from './aws-exports';

+Amplify.configure(config);

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
-  <React.StrictMode>
+  <AmplifyProvider
     <App />
+  </AmplifyProvider>
-  </React.StrictMode>
)
```





App.tsx below.


```tsx:App.txs
import type { FC } from 'react';
import { Amplify } from 'aws-amplify';
// eslint-disable-next-line import/extensions
import '@aws-amplify/ui-react/styles.css';
import awsExports from './aws-exports';

Amplify.configure(awsExports);

const App: FC = () => {
  return (
    <h1>
      Hello Amplify+Vite!
    </h1>
  );
}

export default App;

```

However, when I start the development server in this state (yarn dev), I get the following error
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pc2863ku2wp6mao1ryoe.png)


We update "index.html" as follows. (list the differences)

```html:index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite + React + TS</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
+    <script>
+      window.global = window;
+      window.process = {
+        env: { DEBUG: undefined },
+      };
+      var exports = {};
+    </script>
  </body>
</html>
```

The following initial screen will appear in your browser as a result so far.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ab9260oyn5xjlqpt0f49.png)


#### Source code at this point
https://github.com/akiraabe/my_first_vite/tree/Initial

### Data Model Linkage.

Please refer to the source code as it is time-consuming to describe the steps to link with the data model.

https://github.com/akiraabe/my_first_vite/tree/UsingAmplify
Only data registration and listing are performed.


### Hosting with Amplify CLI
Follow the steps below for hosting. (The reason I use Amplify CLI instead of AWS Management Console is because I want to install WAF on CloudFront.)

* amplify add hosting
* amplify publish

#### amplify add hosting

Execute the following command.

```zsh
amplify add hosting
✔ Select the plugin module to execute · Amazon CloudFront and S3
? Select the environment setup: PROD (S3 with CloudFront using HTTPS)
? hosting bucket name myfirstvite-xxxxxxxxxxxx-hostingbucket
Static webhosting is disabled for the hosting bucket when CloudFront Distribution is enabled.

You can now publish your app using the following command:
Command: amplify publish
```
### amplify publish

Execute the following command

However, this will fail and will be corrected later.

```zsh
amplify publish

'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-node/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
file: /Users/xxxxxxxxmy_first_vite/node_modules/@aws-sdk/credential-provider-node/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js:4:9
2: import { ProviderError } from "@aws-sdk/property-provider";
3: import { Buffer } from "buffer";
4: import { request } from "http";
            ^
5: /**
6:  * @internal
error during build:
Error: 'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/credential-provider-node/node_modules/@aws-sdk/credential-provider-imds/dist/es/remoteProvider/httpRequest.js
```

##### error handling
Make the following modifications to vite.config.ts. Then re-run amplify publish.

```typescript
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

// https://vitejs.dev/config/
export default defineConfig({
+  resolve: {
+    alias: [
+      { find: './runtimeConfig', replacement: './runtimeConfig.browser' },
+      { find: '@', replacement: '/src' },
+    ],
+  },
  plugins: [react()]
})
```
# Impressions
Vite is comfortable to use because the local development server starts up explosively fast (although the code base is not so big this time).
It does take some initial setup, but I felt it was worth it!

## Footnotes

[[1] Scaffolding your first vite project](https://vitejs.dev/guide/#scaffolding-your-first-vite-project)
[[2] AmplifyStudio & Figma](https://qiita.com/akiraabe/items/55f28fe4f721f74eb992)
[[3] AWS AmplifyStudio Tutorial Blog](https://aws.amazon.com/jp/blogs/news/aws-amplify-studio-figma-to-fullstack-react-app-with-minimal-programming/)
[[4] Amplify DataStore Docs](https://docs.amplify.aws/lib/datastore/getting-started/q/platform/js/)