In this article, we are going to walk through the process of building a ReactJS app and then deploy that to the Azure App Service. We will use Azure DevOps to do version control of the app, as well as build and deployment.
This scenario is a little more complex than the scenarios discussed in the previous articles of this series. In case you haven’t read them already, here are the links:
Using Azure DevOps for Build and Deployment of NodeJS application
Using Azure DevOps for NodeJS application optimization using Gulp
You will step through the following activities:
a. Create a React.JS app using the create-react-app utility and then put it under version control of Azure DevOps.
b. Build the optimized version of the App using Build service of Azure DevOps.
c. Use Release Management service of Azure DevOps to deploy the optimized app to a Test environment.
d. As part of the release workflow on test environment, run the test using Jest, Mocha and Selenium frameworks.
While doing all this, please keep in mind that this is not a tutorial on ReactJS and we are not going to go into the details of coding and issues related to it. If you are new to ReactJS, check out React js Tutorial - Getting Started.
Create and clone git repository
In this first step of this walkthrough, we will execute the following:
1. Create a folder that will map to the local repository of git. Call it ReactApp.
2. Create a Team Project or a git repository in your existing team project.
3. Clone the repository created in the step above in VS Code, to the ReactApp folder created earlier
4. Open that repository in VS Code
Now we are ready to create our ReactJS app.
Create ReactJS App
We are going to continue using VS Code for creating our ReactJS app. For this we will use a tool called “create-react-app”. Let us walk through the steps to create and customize a simple ReactJS app that we will later use for build and deployment.
To create this app, use the npm in terminal to get the “create-react-app” tool. Execute the following command:
>npm install create-react-app
After installing, use the tool to create a new react app by executing the following command:
>create-react-app ssgsemsreact
This command will create the folder structure and files necessary for a basic ReactJS app.
A src folder will get created which contains code for the ReactJS app. It will also create a package.json file that contains the configuration of the ReactJS app we just created, as well as add the required node modules. Now that the basic app is created, we can tweak and customize it a bit.
Open the App.js file in the src folder and change the code to something like this:
import React, { Component } from 'react';
import logo from './SSGSLogo.png';
import './App.css';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} alt="SSGS" />
<p>
SSGS IT EDUCON Services Pvt. Ltd.
</p>
<a
className="App-link"
href="http://www.ssgsonline.com"
target="_blank"
rel="noopener noreferrer"
>
Go to Website
</a>
</header>
</div>
);
}
}
export default App;
Ensure that you add the needed files to the src folder i.e. the ones that you refer in the above code like the SSGSLogo.png.
Once the code is ready, you can commit it to the local git repository and then push it to the remote repository which resides in your team project on Azure DevOps.
Create Build Pipeline
React code has to be built(build) for deployment. The Script for the build is already provided by the “Create-React-App” tool. When that script is run, it will create a folder named “build”. We need to deploy this to the targeted Azure App Service. In the build pipeline, we will create an artifact which will contain all the optimized files for deployment to the test environment. Lastly, we will create a .ZIP archive of those contents for deployment.
To create the build pipeline, login to your Azure DevOps account and browse to your team project. Move the mouse cursor over the Pipelines and select build. Click the button to create a new build pipeline. Select the Empty Job in the template selection step. Accept the values of parameters in Pipeline and Get Sources sections.
As a first step, add a task for restoring all node module dependencies by having a “npm install” task. This will install the necessary dependencies on the agent, if they don’t already exist. After this step, add another npm task and set the operation to “Custom”. Set the arguments parameter to “run build”.
This will create the optimized version of the application in the build folder.
Next, add an “Archive files” task. Do the following:
- Set the “build” folder as source to archive,
- “$(Build.ArtifactStagingDirectory)” as the target where the archive should be stored,
- “ReactApp.zip” as the name of the file to be created as archive and
- .ZIP as the format of the archive.
Finally, add the task of “Publish build artifact”. Set “$(Build.ArtifactStagingDirectory)/ReactApp.zip” as the “path to publish”.
When you queue this build, it will select a hosted agent and run the build on that. At the end of a successful build, you will be able to see an artifact named “appdrop” which will contain an archive named “ReactApp.zip”.
Deploy the ReactJS application using Release Pipeline
Plan is to deploy the ReactJS app to a test environment and then run a Selenium test after deployment. We’ll be needing a web application in Azure App Service as a test environment. I will guide you through creating the test environment and you can do the same actions to create a production environment if required.
To create the test environment, login to the Azure Portal and create a “Web App”. Give it an appropriate name such as “ssgsemsreacttest”. This is a placeholder for the ReactJS app that you are going to deploy your app to.
Back into Azure DevOps, create a new Release Pipeline from Pipelines > Release option. Select the “Deploy Node App to Azure App Service” template. In this pipeline, enter the name of the stage that is provided by the template as the “Test Environment”. Add the artifact of the build pipeline that is going to be received from the build output. Select “Latest” as the version of the artifact that should be used for deployment.
In the deployment process, select the Azure subscription that you are using. If necessary, provide the “Authorization” to access that subscription. Once the subscription selection is accepted, from the drop down, select the web application that you have created earlier.
You will find that there is only one task in the pipeline, that is to deploy the app to Azure App Service. It has already picked up the name of the app to deploy to. Select the package or folder. From the selector button, drill down to the .ZIP file that is created under the “appdrop” artifact.
Expand the section of “File Transforms and Variable Substitution Options” and remove the checkmark in the checkbox for “Generate Web.Config”.
In the “Application and Configuration Settings” section, remove the constant that provides id of the Node to make the App Setting text box as blank.
When you create the release, deployment will automatically start. It will upload the build.zip file to the Azure App Service and then unzip it to complete the deployment. You can run the app to check the success of deployment.
What remains in this walkthrough is to create a test that uses Selenium and Mocha. To create a test, go back to VS Code and add a folder named “test” in the root of the application. In this “test” folder, create a file “test.js”.
Before starting to write the code for the Selenium test, add the prerequisite node modules by installing Selenium Webdriver, Chromedriver and Mocha. To do so, run the following commands in the terminal of VS Code.
> npm install selenium-webdriver chromedriver --save
> npm install mocha --save-dev
Now you can begin coding of test.js file. At first, add the require statements to load the node modules:
var assert = require("assert").strict;
var webdriver = require("selenium-webdriver");
Then create some constants that you will use. Observe that the URI is that of the application after it is deployed to the Azure App Service. It is normal that UI test should be carried out only after deployment to the target environment. That is why we want that this test should be run as part of release and not as an activity in the build workflow.
// Application Server
const serverUri = "https://ssgsemsreacttest.azurewebsites.net/";
const appTitle = "React App";
Now you can create the instance of the browser (shadow DOM object) which will be used in the background to access a page and run the test.
var browser = new webdriver.Builder()
.usingServer()
.withCapabilities({ browserName: "chrome" })
.build();
To close the browser after the test, add an afterEach block which will be a function that closes the browser.
afterEach(function() {
// End of test use this.
browser.quit();
})
Now write a function that gets the title of the page and a test that ensures that the title of the page is as required.
function logTitle() {
return new Promise((resolve, reject) => {
browser.getTitle().then(function(title) {
resolve(title);
});
});
}
describe("Home Page", function() {
/**
* Test case to load our application and check the title.
*/
it("Should load the home page and get title", function() {
return new Promise((resolve, reject) => {
browser
.get(serverUri)
.then(logTitle)
.then(title => {
assert.strictEqual(title, appTitle);
resolve();
})
.catch(err => reject(err));
});
});
});
The test is run by an NPM command “npm run test” which in turn executes a react-script to test. This configuration is provided in package.json file created by the create-react-app. The default behavior of this script is to run all the tests and then go into the “Watch” mode so that any changes in the target files will automatically trigger the test. This behavior is good when executing in a standalone mode but not in an automated environment provided by Azure DevOps.
By default, the script does not create any test results output. It is necessary to have such a file that uses a standard format like Junit. To take care of both of these factors, the test line in the script section of package.json should be modified. On windows, your package.json will look like this:
{
"name": "ssgsemsreact",
"version": "0.1.0",
"private": true,
"dependencies": {
"chromedriver": "^2.45.0",
"jest-junit": "^6.2.1",
"mocha": "^5.2.0",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-scripts": "2.1.3",
"selenium-webdriver": "^4.0.0-alpha.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "set CI=true && react-scripts test --reporters=default --reporters=jest-junit",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {}
}
This test will be run by the release after deploying the app to the Azure App Service. So now you can commit and push the code to the Azure DevOps Git repository of the team project.
In the earlier build, we had run the ‘build’ command on the npm task and then created an archive of the ‘build’ folder which got created. The “test” folder foes not get copied though. You need to pass the test to the release pipeline so that after the app is deployed, we will be able to run the test. For this reason, you will need to create another artifact that contains the src folder. This artifact is then used by release management to run the test. You may call this artifact as “testdrop”.
Start by editing the earlier build definition. Add a new task of “Copy Files”. This task will copy all the necessary files and folders to a subfolder named test under Artifact Staging Directory. Copy all .JSON files along with your src folder and test folder.
The final task in our build will be to “Publish build artifact”. Set the name to “testdrop” as mentioned earlier.
You can queue the build now and observe that the new artifact “testdrop” contains all the necessary files and folders.
Now open the release pipeline that you had created earlier to edit it. Add the following tasks and set their parameters as below (Without the quotes):
1. npm install – Provide “$(System.DefaultWorkingDirectory)/_SSGSReactDemo-CI/testdrop” as the Working Folder that contains package.json file. No other change is required.
2. npm custom - Provide “$(System.DefaultWorkingDirectory)/_SSGSReactDemo-CI/testdrop” as the Working Folder that contains package.json file. Enter “install react-scripts –save” as the Command
3. npm custom - Provide “$(System.DefaultWorkingDirectory)/_SSGSReactDemo-CI/testdrop” as the Working Folder that contains package.json file. Enter “run test” as the command
4. Publish Test Results – Set Junit as Test Result format and **/junit.xml as the Test Results File.
Save the release pipeline and create a new release. Ensure that you are using on-premises agent. Although there does not seem to be anything that would prevent us from using Hosted 2017 agent, my attempts to use it, failed.
Summary:
Azure DevOps provides all the necessary support to build, deploy and test React.JS apps. It allows us to use multiple frameworks like Mocha and Selenium to be used in collaboration to run automated tests after the app is deployed to an Azure App Service as a web app.
Thanks to Tim Sommer for his suggestions and for technically reviewing this article.
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Subodh is a Trainer and consultant on Azure DevOps and Scrum. He has an experience of over 33 years in team management, training, consulting, sales, production, software development and deployment. He is an engineer from Pune University and has done his post-graduation from IIT, Madras. He is a Microsoft Most Valuable Professional (MVP) - Developer Technologies (Azure DevOps), Microsoft Certified Trainer (MCT), Microsoft Certified Azure DevOps Engineer Expert, Professional Scrum Developer and Professional Scrum Master (II). He has conducted more than 300 corporate trainings on Microsoft technologies in India, USA, Malaysia, Australia, New Zealand, Singapore, UAE, Philippines and Sri Lanka. He has also completed over 50 consulting assignments - some of which included entire Azure DevOps implementation for the organizations.
He has authored more than 85 tutorials on Azure DevOps, Scrum, TFS and VS ALM which are published on
www.dotnetcurry.com.Subodh is a regular speaker at Microsoft events including Partner Leadership Conclave.You can connect with him on
LinkedIn .