The Foundation: Setting up a React/Express App
While writing the post about creating UrlMem’s front end, I realized there’s a lot to setting up a React app with an Express backend.
There are many five minute tutorials detailing how to do so - but they end up under explaining the good bits.
So this post will be dedicated to explaining and setting up a minimal React app with Express in the backend.
At the end of this post I’ve compiled the sources I used.
Express is a routing library for Node.js. A router lets us decide what a user sees when they visit different parts of our website. For example, I could create a route for urlmem.com/, and different route for urlmem.com/hi.
In UrlMem’s case, I’ll probably have a route for urlmem.com/ that leads to home, and a route for urlmem.com/* that looks at whatever is in place of “*”, and redirects to the associated longer url.
In terminal I created a new folder for the project, and inside of that folder initialized the project using npm init - the information given to npm init isn’t especially important, although the application entry point should be index.js:
Next I installed Express using the --save flag to add it as a dependency to the project.
Then I created a program index.js, with a route for /greet:
Npm doesn’t know to run index.js unless it’s in package.json, so I added “start-dev”: “node index.js” under scripts to package.json:
Now running npm run start-dev ran index.js using node. Then while the command is running, when visiting localhost:5000/greet in a browser the Express app responds by sending the browser “hi”.
We could be finished with the Express portion, but it’s annoying to have to re-run the program when we want to change index.js.
So I installed nodemon, which restarts a command whenever it notices a file change:
Note that I use the --save-dev flag. This adds nodemon as a dependency only necessary during development. When I deploy UrlMem to the public, I won’t need to use nodemon.
In order to put nodemon into practice, I changed the start-dev script in package.json to the following:
I told nodemon to ignore folders node_modules and client, as they don’t require restarting the server.
To see that nodemon was working, I changed the greeting in index.js to “hello” and saved it. When I reloaded localhost:5000/greet I saw the server had updated without me restarting it, so I changed the greeting back to “hi”.
In essence, React is a component-oriented library. Normally HTML is pretty much hard coded - the layout is written, and that’s how it stays.
With React, pieces of HTML are created as components. This makes reusing HTML much easier.
First I installed create-react-app and used it to generate a basic react app in the urlmem-app folder.
Note that I didn’t use the --save flag to make create-react-app a dependency, since after generating the react app, I’d no longer need the tool in the project. Instead I used the -g flag to install the tool globally, so that I can use it for projects later outside of the urlmem-app directory.
Now when I ran npm start from within the react project, the app started up in a browser window at port 3000.
Although the example React app is quite nice, it’s not a URL shortener. So I went into the src folder, and removed all of the code from index.css and App.css.
Next I deleted logo.svg, and in App.js removed the import for logo.svg.
The last removal was of the .git folder from client, as it’s only for keeping the basic react app up to date, and I’d be making changes of my own.
Afterwards I made some edits to App.js, which is the main file for a React project:
Note that before, App was just a function. Now it’s a class extending Component. Components can be written both ways - learn more about components by reading the react docs.
Now, provided the Express app is running in a different terminal, App tries to get data from the Express app’s /greet route, and tells us if it’s successful (it wasn’t):
The React app couldn’t successfully connect to the Express server because React is running on port 3000, and Express on port 5000. So the React app ends up receiving junk from it’s own server, not from the Express server.
The solution is to tell React to use a proxy in client/package.json:
Now after restarting the React app, Express could talk to React:
At this point I was having to run npm run start-dev in the urlmem-app folder, and in another terminal run the same command in the urlmem-app/client folder.
To fix this I installed concurrently, a cross-platform solution for running two commands at the same time. It should be installed in urlmem-app, not in client:
Then I changed the start-dev script in urlmem-app/package.json to run both the React app and the Express app:
Now running npm run start-dev from within the urlmem-app folder ran the express and react app, updating the appropriate app when files changed.
I’ve already started on the different components for the website, so stay tuned for the next post, where I’ll design the urlmem website.
Get occasional updates on projects!
Get occasional updates on projects!