{"id":287196,"date":"2019-05-10T12:54:40","date_gmt":"2019-05-10T19:54:40","guid":{"rendered":"http:\/\/css-tricks.com\/?p=287196"},"modified":"2019-05-25T06:51:07","modified_gmt":"2019-05-25T13:51:07","slug":"deploying-a-client-side-rendered-create-react-app-to-microsoft-azure","status":"publish","type":"post","link":"https:\/\/css-tricks.com\/deploying-a-client-side-rendered-create-react-app-to-microsoft-azure\/","title":{"rendered":"Deploying a Client-Side Rendered create-react-app to Microsoft Azure"},"content":{"rendered":"
Deploying a React app to Microsoft Azure is simple. Except that… it isn\u2019t. The devil is in the details. If you’re looking to deploy a create-react-app \u2014 or a similar style front-end JavaScript framework that requires First, a quick story.<\/p>\n <\/p>\n Back in 2016, when Donovan Brown, a Senior DevOps Program Manager at Microsoft, had given a “but it works on my machine speech”<\/a> at Microsoft Connect that year, I was still in my preliminary stages as a web developer. His talk was about micro-services and containers.<\/p>\n […] Gone are the days when your manager comes running into your office and she is frantic and she has found a bug. And no matter how hard I try, I can’t reproduce it and it works perfectly on my machine. She says: fine Donovan, then we are going to ship your machine because that is the only place where it works. But I like my machine, so I’m not going to let her ship it…<\/p><\/blockquote>\n I had a similar sort of challenge, but it had to do with routing. I was working on a website with a React front end and ASP.NET Core back end, hosted as two separate projects that were deployed to Microsoft Azure. This meant we could deploy both apps separately and enjoy the benefits that comes with separation of concern. We also know who to One day I pushed some new code to our staging servers. I received a message shortly after telling me the website was failing on page refresh. It was throwing a 404 error. At first, I didn\u2019t think it was my responsibility to fix the error. It had to be some server configuration issue. Turns out I was both right and wrong. <\/p>\n I was right to know it was a server configuration issue (though at the time, I didn\u2019t know it had to do with routing). I was wrong to deny it my responsibility. It was only after I went on a web searching rampage that I found a use case for deploying a create-react-app to Azure under the Deployment tab on the official documentation page<\/a>. <\/p>\n When building a React app for production<\/a> (assuming we\u2019re are using create-react-app<\/a>), it\u2019s worth noting the folders that get generated. Running Generally, the build folder will have this structure:<\/p>\n React Router uses the HTML5 If you use routers that use the HTML5 pushState history API under the hood (for example, React Router with browserHistory), many static file servers will fail. For example, if you used React Router with a route for \/todos\/42, the development server will respond to localhost:3000\/todos\/42 properly, but an Express serving a production build as above will not. This is because when there is a fresh page load for a \/todos\/42, the server looks for the file build\/todos\/42 and does not find it. The server needs to be configured to respond to a request to \/todos\/42 by serving index.html.<\/p><\/blockquote>\n Different servers require different configuration. Express, for example, requires this:<\/p>\n …as documented in the create-react-app docs<\/a>. Keep in mind though, this assumes that we\u2019re hosting create-react-app at the server root<\/strong>, which is making use of a wildcard route ( Since my front-end (create-react-app) and back-end (ASP.NET) were two different projects, serving static files by navigating the directory was sort of an impossibility<\/em>.<\/p>\n In fact, since we are deploying a static app, we do not need the back-end. As Burke Holland put it: “Static” means that we aren\u2019t deploying any server code; just the front-end files.<\/p>\n I keep mentioning ASP.NET here because during the course of my research, I figured configuring Azure required a configuration file in a To get started, if you do not already have a Azure account, get a free trial<\/a> then head over to the Azure portal<\/a>.<\/p>\n For example, the Deployment<\/strong> Center<\/strong> is where the app deployment is managed, Slots<\/strong> is where things like staging, production, test are managed. Configuration<\/strong> is where things like environmental variables, node versions and \u2014 an important one \u2014 Kudu<\/a> are managed<\/a>.<\/p>\n The overview screen shows a general view of the application Status, URL… Click on the URL to see the live site.<\/p>\n The app is up and running!<\/p>\n What we\u2019ve done is create a new App Service<\/a>, but we have none of our code on Azure yet. As said earlier, all we need to do is to feed Azure the content of the build folder generated by building React for production, but we don\u2019t have one yet. So let\u2019s go local and get some React app.<\/p>\n We need to create a new React app<\/a>, and install react-router<\/a> as a dependency.<\/p>\n We also want to install react-router ( All things being equal, starting the app with pushState<\/code>-based routing \u2014 to Microsoft Azure, I believe this article will serve you well. We\u2019re going to try to avoid the headaches of client and server side routing reconciliation.<\/p>\ngit blame<\/code> if and when something goes wrong. But it had downsides as well, as front-end vs. back-end routing reconciliation was one of those downsides.<\/p>\nBuilding React for production<\/h3>\n
npm run build<\/code> will generate a build folder where an optimized static version of the application lives. To get the application on a live server, all we need do is feed the server the content of the build folder. If we were working on localhost<\/strong>, there is no live server<\/em> involved, so it is not always equivalent to having the application on a live server.<\/p>\n\u2192 build\r\n \u2192 static\r\n \u2192 css\r\n \u2192 css files\r\n \u2192 js\r\n \u2192 js files\r\n \u2192 media\r\n \u2192 media files\r\n \u2192 index.html\r\n \u2192 other files...<\/code><\/pre>\nClient-side routing with React Router<\/h3>\n
pushState<\/code> history API<\/a> internally. What pushState<\/code> does is quite interesting. For example, navigating (or using Link<\/a> in react router) from the page https:\/\/css-tricks.com<\/code> to the page https:\/\/css-tricks.com\/archives\/<\/code> will cause the URL bar to display https:\/\/css-tricks.com\/archives\/<\/code> but won’t cause the browser to load the page \/archives<\/code> or even check that it exists. Couple this with the component-based model of React, it becomes a thing to change routes while displaying different pages based on those routes \u2014 without the all-seeing eye of the server trying to serve a page in its own directory. What happens, then, when we introduce servers by pushing the code to a live server<\/em>? The docs tell it better<\/a>:<\/p>\napp.get('*', (req, res) => {\r\n res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));\r\n});<\/code><\/pre>\n*<\/code>) that catches all route and respond to all route request by serving the index.html<\/code> file in the build folder which sits at the root of the server application. Also, this is tightly coupled with the back-end. If that\u2019s the case, we would most likely have this kind of folder structure (assuming the back-end is in NodeJS):<\/p>\n\u2192 Server\r\n \u2192 Client (this is where your react code goes)\r\n \u2192 build (this is the build folder, after you npm run build)\r\n \u2192 src\r\n \u2192 node_modules\r\n \u2192 package.json\r\n \u2192 other front-end files and folders\r\n \u2192 Other back-end files and folders<\/code><\/pre>\nwwwroot<\/code> folder and ASP.NET’s folder structure typically has a wwwroot<\/code> folder. Remember the application\u2019s back-end was in ASP.NET? But that\u2019s just about it. The wwwroot<\/code> folder seemed to be hidden somewhere on Azure. And I can\u2019t show you without deploying a create-react-app<\/code>. So let\u2019s go do that.<\/p><\/blockquote>\nGetting started with App Services on Microsoft Azure<\/h3>\n
\n
\nNavigating on the Azure portal from All services, to Web, to App services<\/p>\n
<\/figure>\n<\/li>\n
\n
\n


Going local<\/h3>\n
npx create-react-app azure-react-demo\r\ncd azure-react-demo<\/code><\/pre>\nreact-router-dom<\/code>, actually)<\/p>\nnpm i react-router-dom<\/code><\/pre>\nnpm start<\/code>, we should get the default page.<\/p>\n