DEV Community

Cover image for Webpack Dev Server: Setting up proxy
Sana Mumtaz
Sana Mumtaz

Posted on • Edited on

Webpack Dev Server: Setting up proxy

In this article, I'll show you how to configure webpack-dev-server for proxying requests from React frontend to Node/Express backend.

Getting Started

I won't go into much details on how to set up React, Webpack and Babel. You can either create the project from scratch or you can do the following:

Configure Frontend

1- Use Create React App

Run create-react-app to create React frontend for your web app.

 npx create-react-app my-app-name 
Enter fullscreen mode Exit fullscreen mode

2- Configure Webpack

Add webpack and its relevant packages to your project.

 yarn add webpack webpack-cli webpack-dev-server --dev yarn add html-webpack-plugin --dev 
Enter fullscreen mode Exit fullscreen mode

I'll be using yarn throughout this article
At the root of project folder, create file webpack.config.js. I won't go into details of the configuration as its very basic.

 const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') module.exports = { entry: { basicApp: { import: './src/index.js', filename: 'basicApp.js' } }, output: { path: path.resolve(__dirname, 'build/static') }, devServer: { port: 3000, hot: true, open: true, }, resolve: { extensions: ['.jsx', '.js', '.json'] }, module: { rules: [ { test: /\.(js)x?$/, exclude: /node_modules/, use: [ { loader: 'babel-loader' } ] }, { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: 'asset/resource' }, { test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: 'asset/inline' } ] }, plugins: [ new HtmlWebpackPlugin({ template: './public/index.html' }) ] } 
Enter fullscreen mode Exit fullscreen mode

And make the following change in the package.json:

 "scripts": { "start": "webpack serve --mode development", "build": "webpack --mode production", ... } 
Enter fullscreen mode Exit fullscreen mode

3- Configure Babel

Now before you try to run the app, configure Babel compiler. Install babel and relevant packages.

 yarn add @babel/core @babel/preset-env @babel/preset-react babel-loader --dev yarn add css-loader style-loader --dev 
Enter fullscreen mode Exit fullscreen mode

At root of project, create file .babelrc:

 { "presets": [ "@babel/preset-env", [ "@babel/preset-react", { "runtime": "automatic" } ] ] } 
Enter fullscreen mode Exit fullscreen mode

You have successfully configured the frontend of your app.

Configure Backend

Add Express to the project:

 yarn add express 
Enter fullscreen mode Exit fullscreen mode

It's your choice whether you set up the backend separately or in the same directory. I set it up in the same dir. Create file backend/server.js at the root.

 const express = require("express") const path = require("path") const app = express() const DIST_DIR = path.join(__dirname, 'build/static') const HTML_FILE = path.join(DIST_DIR, 'index.html') app.use(express.static(DIST_DIR)) app.get('/', (req, res) => { res.sendFile(HTML_FILE) }) app.get('/api/ping', (req, res) => { res.send('pong') }) app.listen(5000) 
Enter fullscreen mode Exit fullscreen mode

In dev mode of this set up, frontend runs at localhost:3000 and backend runs at localhost:5000. Hence, you need to connect frontend to backend so that querying on locahost:3000/api/ping hits the backend localhost:5000/api/ping. For this you can configure proxy in webpack.config.js:

 devServer: { ... proxy: { '/api': { target: 'http://localhost:3000', router: () => 'http://localhost:5000', logLevel: 'debug' /*optional*/ } } } 
Enter fullscreen mode Exit fullscreen mode

Now any request of form /api/** will be directed to port 5000.

Run the project

To view output of ping API call, you can make small edit to App.js:

 import { useState } from "react"; import logo from "./logo.svg"; import "./App.css"; function App() { const [pingResponse, setPingResponse] = useState(""); const pingBackend = () => { fetch("/api/ping", { method: "GET", }) .then((response) => response.text().then(function (text) { setPingResponse(text); }) ) .catch((err) => console.log(err)); }; return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <button onClick={pingBackend}>Ping Backend</button>  {pingResponse && <p>Backend Responded with '{pingResponse}'</p>}  </header>  </div>  ); } export default App; 
Enter fullscreen mode Exit fullscreen mode

You can run the frontend and backend from two terminals. (Recommended: concurrently)

 //in one terminal yarn start //in other terminal yarn build //optional node backend/server.js 
Enter fullscreen mode Exit fullscreen mode

App Output
We've successfully connected the frontend to backend. You can get the code from my GitHub.

GitHub logo sanamumtaz / react-webpack-backend-proxy

Configuring Webpack Dev Server to proxy request from React frontend to Node.js/Express backend.



Share your thoughts. Feedback's always welcome :)

Top comments (1)

Collapse
 
kritidipto1234 profile image
kritidipto-1234

Ping Pong