Copyright Derek O'Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.
Up to this point, we have been running the client-side and server-side on two separate servers. This is useful when we are developing an application. However, in the real-world, we need to host our entire application on a single deployment server.
To combine the client-side and server-side in the same server, we add a new package.json file in the project's root folder, as shown below:
/package.json
{ "name": "development", "version": "1.0.0", "description": "Local host Development Server", "main": "server.js", "scripts": { "start": "npm start --prefix server" }, "dependencies": { "express": "^4.16.3" }, "author": "Derek O Reilly", "license": "ISC" }
"main": "server.js",
The command "main": "server.js" identifies the file server.js as being the file that holds the server code.
"start": "npm start --prefix server"
The command "start": "npm start --prefix server" identifies server as the folder that holds the server.js file
Create a package.json file in the root directory of the project and copy the content from above into it.
We adjust the server/server.js file, as shown below:
server/server.js
const express = require('express') const app = express() app.use(require(`body-parser`).json()) console.log("Development mode. Running on local host server") require(`dotenv`).config({path:`./config/.env`}) app.use(require(`cors`)({credentials: true, origin: process.env.LOCAL_HOST})) const path = require("path") const appPath = path.join(__dirname,"..","client","build") app.use(express.static(appPath)) app.get('/', (req, res) => { res.sendFile(path.resolve(appPath, "index.html")) }) // Routers app.use(require(`./routes/cars`)) // Port app.listen(process.env.SERVER_PORT, () => { console.log(`Connected to port ${process.env.SERVER_PORT}`) }) // Error 404 app.use((req, res, next) => {next(createError(404))}) // Other errors app.use(function (err, req, res, next) { console.error(err.message) if (!err.statusCode) { err.statusCode = 503 } res.status(err.statusCode).send(err.message) })
const path = require("path") const appPath = path.join(__dirname,"..","client","build") app.use(express.static(appPath))
This code identifies the folder ../client/build as holding the client-side static code.
app.get('/', (req, res) => { res.sendFile(path.resolve(appPath, "index.html")) })
The client-side start point is index.html inside the appPath folder (i.e. the folder ../client/build)
When running a deployment server, the client-side code must be moved into an optimised folder. The folder is called build. The build folder is placed in the client folder. In order to create the client/build folder and place the optimised client-side code inside it, we run the rpm run build command from inside the client folder, as shown below:
npm run build
Copy the server_side_routing project from here into a new folder called deploy. From inside the deploy/client folder, run the command npm run build. Take a look at the files that are created inside the deploy/client/build folder.
If the build generates an error, run the code below:
c:\nodejs_projects\deploy\client> npm audit fix --force
If this does not work, run the code below:
c:\nodejs_projects\deploy\client> npm install react-scripts@latest
The deployment server is run by calling the command npm start from the project's root folder, as shown below:
The deployment will be available at port 4000 on the browser, as shown below:
Overwrite the server/server.js file with the content from above.
The origional client-side and server-side development servers can still run. Run client-side and server-side servers. Rename the Colour column in the React CarTable component to Color. The browser will immediately update to show the change made in the code. Change one of the car details in the server/cars.js router file. If you refresh the browser, the changes will take effect.
Run the deployment server by calling the command npm start from inside the root folder. Make a change to the clent-side code. The client-side change will not be shown in the browser. In order for the client-side change to take effect, you will need to re-build the project using the npm run build command.
Run the deployment server by calling the command npm start from inside the root folder. Make a change to the server-side code. The server-side change will not be shown in the browser. In order for the server-side change to take effect, you will need to re-start the project using the npm start command.
From the exercises above, we can see that using a client-side and server-side development server allows us to easily test modifications to our code. We only move our application to a deployment server when we have finished development and testing of our applicaiton.
The full project code for the "Cars" Worked Example that is described below can be downloaded from this link.
/package.json
{ "name": "development", "version": "1.0.0", "description": "Local host Development Server", "main": "server.js", "scripts": { "start": "npm start --prefix server" }, "dependencies": { "express": "^4.16.3" }, "author": "Derek O Reilly", "license": "ISC" }
No changes are needed on the client-side.
server/server.js
const express = require('express') const app = express() app.use(require(`body-parser`).json()) console.log("Development mode. Running on local host server") require(`dotenv`).config({path:`./config/.env`}) app.use(require(`cors`)({credentials: true, origin: process.env.LOCAL_HOST})) const path = require("path") const appPath = path.join(__dirname,"..","client","build") app.use(express.static(appPath)) app.get('/', (req, res) => { res.sendFile(path.resolve(appPath, "index.html")) }) // Routers app.use(require(`./routes/cars`)) // Port app.listen(process.env.SERVER_PORT, () => { console.log(`Connected to port ${process.env.SERVER_PORT}`) }) // Error 404 app.use((req, res, next) => {next(createError(404))}) // Other errors app.use(function (err, req, res, next) { console.error(err.message) if (!err.statusCode) { err.statusCode = 503 } res.status(err.statusCode).send(err.message) })
Copyright Derek O' Reilly, Dundalk Institute of Technology (DkIT), Dundalk, Co. Louth, Ireland.