Deploying an Express, Node.js, React App (with TypeScript) to Azure Web Apps Using GitHub Actions
Introduction
In this post, I will discuss building a basic Express-Node app in TypeScript with a React frontend and deploying it to Azure Web Apps with GitHub Actions. This was a tedious process that involved piecing together steps from various blog posts and StackOverflow threads. I have linked them below in the references.
Here is the folder structure we will be setting up.
1. Initialise the Project
Create the root folder for your project and inside it, run the following command to initialise the project. This will create a package.json
file.
npm init -y
2. Install Dependencies
Run the following commands in the root folder to install the required packages. The save-dev flag installs the packages as development dependencies. We will use ts-node
during local development to run TypeScript files directly, without the need for precompilation using tsc
. concurrently
will be used to run the React frontend and Express servers at the same time.
npm install express
npm install typescript tslint ts-node --save-dev
npm install @types/express @types/node --save-dev
npm install concurrently nodemon --save-dev
3. TypeScript Config Setup
We will use ts-lint
to check for readability, maintainability, and functionality errors. Run the following command in the root folder to create the tslint.json
file.
tslint --init
Next, create a tsconfig.json
file and add the following to it. The options can be added or changed as required.
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "./dist",
"esModuleInterop": true,
"baseUrl": ".",
"paths": {
"*": ["node_modules/*"]
},
},
"include": ["server/**/*"]
}
4. React Client
In the root folder, run the following command to set up the React frontend with TypeScript.
npx create-react-app client --template typescript
Make sure the package.json
is in the client folder as shown. The build
folder will be created on running the build script which we will do later.
Add the following line to package.json in the client
folder. This is required during local development to proxy the requests to our Express server.
"proxy": "http://localhost:5000/"
5. Server
In the root folder, create a folder named server and create a file server.ts
in it. Add the following code to it.
The express server runs on port 5000. We have a simple hello API and also code to display the React app when requested, which will be required when deployed.
6. package.json
Add the following to the package.json in the server
folder.
"scripts": {
"start": "node dist/server.js",
"prebuild": "tslint -c tslint.json -p tsconfig.json --fix",
"build": "tsc --project .",
"build-prod": "cd client && npm install && npm run build && cd .. && npm install && npm run build",
"server": "nodemon --verbose --watch \"server\" --ext \"ts,json\" --exec ts-node server/server.ts",
"client": "cd client && npm start && cd ..",
"dev": "concurrently \"npm run client\" \"npm run server\""
}
The build-prod
script will be used during deployment. It will create a dist
folder with the compiled JavaScript from the TypeScript backend and a build
folder inside the client folder which will have the static files for the frontend. The client code is built first because the server code later serves the generated build
folder.
The dev
script will be used during local development.
7. Make HTTP requests from React to Node
Call the hello API from React by adding the following code in your React component, for eg, in App.tsx
.
useEffect(() => {
const sayHello = async () => {
const response = await fetch("/api/hello");
const body = await response.json();
console.log(body);
};
sayHello();
}, []);
Run the following command in the root folder to start the localhost server.
npm run dev
This should open http://localhost:3000 in your browser and should log “Hello” in your browser console.
8. Web.config
Azure Web Apps use IIS webservers that require a web.config
file. Add the following to your root folder. This will use the server.js
file in the dist
folder as the Node.js application.
9. Create Azure Web App Resource
Push your code to a GitHub repo.
Create an Azure Web App from the Azure portal. Choose the runtime stack as shown.
Once the app is created, follow these steps to set up the GitHub Actions integration to your repo. This will create a .yml
workflow file in your GitHub repository. Make the change as shown in line 26 to use the build-prod
script we defined earlier in package.json
.
Commit your changes and wait for the Action to complete. Your app should be deployed to Azure. Phew!
For any diagnostics, you can navigate to the Kudu console for your web app by adding .scm to your web app address. For example, if your address is https://react-node-app.azurewebsites.net, go to https://react-node-app.scm.azurewebsites.net/DebugConsole.