.Net Core Backend + React.js Frontend — Optimizing the development time experience

I’ve seen some chatter on Twitter this week that the enforced home time due to the Coronavirus will lead to much more blogging and OSS activity. Hopefully all the social distance measures work out and we’ll have time and energy to be concerned about relatively unimportant things like software development in the weeks to come. Or maybe this kind of thing is just a nice distraction.

As a follow up to my last post a while back titled Choosing a “Modern” React.js + .Net Core Stack, I want to talk about how our team is trying to create a productive development time experience for working with both the React.js frontend and the .Net Core backend. In this case we’re really building out a replacement for a large feature in an existing ASP.Net MVC application, so even though we’ve opted for a brand new ASP.Net Core backend for the new feature, we’ve got to play nice with the existing application. To that end, out new React.js bundle is going to be hosted in production by the existing MVC5 application in a minimalistic Razor page (really just the inevitable <div id="main" /> tag and a <script /> tag that serves up the Javascript bundle. I should also point out that the React.js bundle is created at build time in the CI/CD pipelines by Parcel.js.

All that being said, the production time architecture simply looks like this, with the production database, the existing MVC5 web application, and our new ASP.Net Core service all being hosted on Azure:

ProductionMode

So that’s in production, but at development time we need to have a little different configuration. After a couple iterations, our development time model for running the application locally looks like this:

DevelopmentMode

I feel strongly that most development tasks can and should be done with a test driven development approach (but I’m not demanding any kind of test-first purity as long as the tests are actually written concurrently with new code) — especially on the .Net backend side. Even quite a bit of the React.js components and any other Javascript code can be written inside of unit testing cycles using the Jest watch mode.

However, there’s still a lot of times when you want to run the application to see the user interface itself and work on the interactions between the full stack. To that end we did want a configuration that allowed developers to run everything locally on their own development box.

Since I’m a big believer in “per developer development databases,” I set up a little bit of project automation with Bullseye to spin up Sql Server in a Docker container, provision the application databases with the existing RoundHousE migrations, and add some sample data as necessary. I’ll write a separate blog post someday (maybe) about this because I thought it came together pretty smoothly, but you still had to piece things together across a lot of disjointed blog posts and online documentation.

Running the .Net Core backend locally is easy with ASP.Net Core. Using the Oakton.AspNetCore command line extensions, we can spin up the application at the command line or an IDE run configuration with dotnet run -- -e Development to run the application in “development” mode with configuration pointing at local resources (i.e., appsettings.Development.json).

Running the front end React.js code was a little trickier in our case because of its reliance on so much server side state. We very initially used hard-coded JSON data in the React.js code itself to get started, but we quickly outgrew that. We later kicked the tires on stand in API tools like json-server. In the end, we opted to run the real backing API web service when working with the React.js application to avoid having any incompatibilities between a fake web service and the real thing. I don’t know that I’d opt to make that same decision in every case, but I think it’s going to work out in this one.

For UI development, I’m a huge fan of using React.js’s hot module replacement mode for quick change loop / feedback cycles at development time. Using Parcel.js’s development server, you can serve up your React.js bundle in a minimal HTML page where the React.js components are automatically rebuilt and refreshed on the page while maintaining the existing state of the application whenever the backing code files are changed.

As a hot tip though, if you’re going to try to use the hot replacement mode while also talking to a local ASP.Net Core, disable the HTTPS support in development mode on the .Net side of things. I found that it knocks out the websockets communication that Parcel.js uses to reload the React.js components.

Using Dotenv for Javascript Environment Variables

One of the first issues we faced was that the API’s URL location is different locally versus in production mode, and the code that made HTTP calls in the React.js bundle needed to be aware of that. Fortunately, we’re using Parcel.js and it has out of the box support for the dotenv library to support the idea of environment variables within the Javascript bundled code for configuration items like the base url of our backing web service.

The environment variables are defined in text files with the naming convention `.env.[profile]`. For the “development” mode, we added a file parallel to the package.json file called .env.developmentthat consists for now of just this line:

BASE_URL=http://localhost:5000

When you run the Parcel.js development server with the hot module replacement, it uses the “development” profile and the value of “BASE_URL” in the file above will be embedded into the bundled Javascript accessible from the global process.env object.

In the Javascript file in our React.js bundle that makes HTTP calls to the backend service, we lookup the base url for the backend service like this:

var baseUrl = '';

// dotenv places the values from the file above
// into the "process.env" object at build time
if (process.env.BASE_URL){
    baseUrl = process.env.BASE_URL;
}

 

There’s still some ongoing work around security via JWT tokens, but right now we’re able to run the React.js bundle in the hot replacement mode, but still connect to the locally running ASP.Net Core web service and I’m happy with the development experience so far.

4 thoughts on “.Net Core Backend + React.js Frontend — Optimizing the development time experience

      1. Oles Stovbenko

        Yes. But “baseUrl” was empty in production bundle until I changed it to “REACT_APP_BASE_URL”.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s