Deploying An Express, Node - JS, React App (With TypeScript) To Azure Web Apps Using GitHub Actions - by Mehnaz Yunus - Geek Culture - Medium
Deploying An Express, Node - JS, React App (With TypeScript) To Azure Web Apps Using GitHub Actions - by Mehnaz Yunus - Geek Culture - Medium
Become a member
29 1
Open in app
Search Write
Source: Google
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.
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
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.
1 import express from "express";
2 import path from "path";
3
4 const PORT = process.env.PORT || 5000;
5
6 const app = express();
7
8 app.use(express.json());
9 // Serve the React static files after build
10 app.use(express.static("../client/build"));
11
12 app.listen(PORT, () => {
13 console.log(`Server listening on ${PORT}`);
14 });
15
16 app.get("/api/hello", (req, res) => {
17 res.send({ message: "Hello" });
18 });
19
20 // All other unmatched requests will return the React app
21 app.get("/", (req, res) => {
22 res.sendFile(path.resolve(__dirname, "client", "build", "index.html"));
23 });
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.
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.
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
1 <?xml version="1.0"?>
2
3 <configuration>
4 <system.webServer>
5 <handlers>
6 <!-- indicates that the server.js file is a node.js application to be handled by the
7 <add name="iisnode" path="dist/server.js" verb="*" modules="iisnode" />
8 </handlers>
9 <staticContent>
10 <mimeMap fileExtension=".json" mimeType="application/json" />
11 </staticContent>
12 <rewrite>
13 <rules>
14 <!-- Do not interfere with requests for node-inspector debugging -->
15 <rule name="NodeInspector" patternSyntax="ECMAScript" stopProcessing="true">
16 <match url="^server.js\/debug[\/]?" />
17 </rule>
18
19 <!-- First we consider whether the incoming URL matches a physical file in the /p
20 <rule name="StaticContent">
21 <action type="Rewrite" url="public{REQUEST_URI}"/>
22 </rule>
23
24 <!-- All other URLs are mapped to the node.js site entry point -->
25 <rule name="DynamicContent">
26 <conditions>
27 <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
28 </conditions>
29 <action type="Rewrite" url="dist/server.js"/>
30 </rule>
31 </rules>
32 </rewrite>
33 </system.webServer>
34 </configuration>
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 .
1 # Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy
2 # More GitHub Actions for Azure: https://github.com/Azure/actions
3
4 name: Build and deploy Node.js app to Azure Web App
5
6 on:
7 push:
8 branches:
9 - main
10 workflow_dispatch:
11
12 jobs:
13 build-and-deploy:
14 runs-on: windows-latest
15
16 steps:
17 - name: 'Checkout Github Action'
18 uses: actions/checkout@v2
19
20 - name: Set up Node.js version
21 uses: actions/setup-node@v1
22 with:
23 node-version: "14.x"
24
25 - name: npm install, build
26 run: npm run build-prod
27
28 - name: "Deploy to Azure Web App"
29 id: deploy-to-webapp
30 uses: azure/webapps-deploy@v2
31 with:
32 app-name: "needs-workshop"
33 slot-name: "dev"
34 publish-profile: ${{ secrets.AzureAppService_PublishProfile_xxxx }}
35 package: .
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.
References
Node, TypeScript, Azure Web Apps by Matthew Barben
How to Create a React App with a Node Backend: The Complete Guide
(freecodecamp.org)
61 2.1K 14
Devansh- Machine Learning Made … in Geek Cult… Anshul Borawake in Geek Culture
See all from Mehnaz Yunus See all from Geek Culture
How to deploy a Vite React app to How to build effective React Native
Azure App Service using CI/CD… CI/CD using GitHub Actions for…
A step-by-step guide on how to deploy your For any developer, just developing the app,
Vite React app to Azure App Service, and us… and transforming the requirements into the…
11 2 148 1
Lists
Stories to Help You Grow as a General Coding Knowledge
Software Developer 20 stories · 539 saves
19 stories · 519 saves
118 1
10 84 1