DEV Community

Cover image for React Integration with Django Using Babel & Webpack
Arindam Sahoo
Arindam Sahoo

Posted on

React Integration with Django Using Babel & Webpack

Hi Devs,

In this post, let's try to add React to our Django Project. It is slightly hectic to remember all the steps, so this post will also help me jot down all of them.

Let me just let you know the Current Directory Structure I am assuming you have before getting started:

├── project
│   ├── app
│   │   ├── migrations
│   │   ├── __init__.py
│   │   ├── admin.py
│   │   ├── apps.py
│   │   ├── models.py
│   │   ├── serializers.py
│   │   ├── tests.py
│   │   ├── urls.py
│   │   └── views.py
│   ├── project
│   │   ├── migrations
│   │   ├── __init__.py
│   │   ├── asgi.py
│   │   ├── settings.py
│   │   ├── urls.py
│   │   └── wsgi.py
│   └── manage.py
Enter fullscreen mode Exit fullscreen mode

Now, we have to make another Django App called frontend by typing

django-admin startapp frontend
Enter fullscreen mode Exit fullscreen mode

Inside the Project Directory.

Then we need to get inside the frontend directory and make a few folders inside it for static and templating files. The apps.py file in this frontend directory is going to store all the kinds of stuff related to our frontend.

And our frontend should look like this:

├── frontend
│   ├── migrations
│   │   └── __init__.py
│   ├── src
│   │   ├── components
│   │   │   ├── App.js
│   │   │   └── Home.js
│   │   └── index.js
│   ├── static
│   │   ├── css
│   │   ├── frontend
│   │   └── images
│   ├── templates
│   │   └── frontend
│   │       └── index.html
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── serializers.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
Enter fullscreen mode Exit fullscreen mode

Now, in the frontend directory we will type in the command:

npm init -y
Enter fullscreen mode Exit fullscreen mode

This is used to initialize a new Node.js project using npm with default values. It automatically generates a package.json file for your project without prompting you for any input.

Following this, we need to type in these commands:

npm i webpack-cli --save-dev
Enter fullscreen mode Exit fullscreen mode

The npm i webpack-cli --save-dev command installs the webpack-cli package as a development dependency. Webpack is a module bundler for JavaScript applications, and webpack-cli provides a command-line interface for webpack.

npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev
Enter fullscreen mode Exit fullscreen mode

The npm i @babel/core babel-loader @babel/preset-env @babel/preset-react --save-dev command installs several Babel-related packages as development dependencies:

  • @babel/core: This is the core Babel compiler.
  • babel-loader: This is a webpack loader that allows you to transpile your JavaScript code using Babel during the webpack build process.
  • @babel/preset-env: This preset allows you to use the latest ECMAScript features and automatically determines the Babel plugins and polyfills needed based on your target environments.
  • @babel/preset-react: This preset is specifically for React applications. It enables Babel to understand and transform JSX syntax used in React components.
npm i react react-dom
Enter fullscreen mode Exit fullscreen mode

The npm install react react-dom installs React and ReactDOM as regular dependencies, and they will be added to the "dependencies" section of your package.json file. React is the library for building user interfaces, and ReactDOM is the package that provides integration with the DOM.

npm i @babel/plugin-proposal-class-properties
Enter fullscreen mode Exit fullscreen mode

This command installs the Babel plugin @babel/plugin-proposal-class-properties. This plugin is used to enable support for class properties in your JavaScript code. Class properties allow you to define properties directly on a class rather than in a constructor.

npm i react-router-dom
Enter fullscreen mode Exit fullscreen mode

It installs the react-router-dom package, which is a package for handling routing in React applications, and will help us reroute the pages so that we can go, well, two different pages from a React App.

Now, after all these, we need to set up some configuration scripts that are going to run and handle our Webpack and our Babel. One can copy these files from here because they are going to be the same thing for everyone.

Firstly, we are going to create a new file in the frontend directory named babel.config.json and paste the following into it.

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "node": "10"
        }
      }
    ],
    "@babel/preset-react"
  ],
  "plugins": ["@babel/plugin-proposal-class-properties"]
}
Enter fullscreen mode Exit fullscreen mode

Next, create another file and name it as webpack.config.js and paste the following into it.

const path = require("path");
const webpack = require("webpack");

module.exports = {
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "./static/frontend"),
    filename: "[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
    ],
  },
  optimization: {
    minimize: true,
  },
  plugins: [
    new webpack.DefinePlugin({
      "process.env": {
        // This has effect on the react lib size
        NODE_ENV: JSON.stringify("production"),
      },
    }),
  ],
};
Enter fullscreen mode Exit fullscreen mode

Just to let the reader know, what Webpack does is bundle all of our JavaScript into one file. We can bundle it into multiple files, but anyway, it just takes all this JavaScript code we have makes a bundle of it, and then serves that one file to the browser.

Now, let's move on to the next step. We are going to go to package.json file and what we need to do inside here is where it says scripts, we need to add two scripts, which are going to run this Webpack. The first thing we're going to add is the dev script. What this is going to do is tell us that, we want Webpack to run, we want to run a neat development mode and we want it to be in watch mode. Next, we're going to add a build script.

"scripts": {
    "dev": "webpack --mode development --watch",
    "build": "webpack --mode production"
}
Enter fullscreen mode Exit fullscreen mode

Next up, we are supposed to create an index.js file inside the src directory. What we need to do now is to make our Django App render a page that React will take control of. If you haven't used Django & React before then this isn't going to make much sense. But what we are up to is to have our Django Application render a template, which is going to be some vanilla, plain HTML, and which our React will take over and fill in. So, we will technically have the Django backend rendering the template but then React will manage it after that. For the time being, let's go to the index.html file inside frontend folder in templates directory and paste the following:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Title</title>
    {% load static %}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="{% static "css/index.css" %}"
    />
  </head>
  <body>
    <div id="main">
      <div id="app"></div>
    </div>

    <script src="{% static "frontend/main.js" %}"></script>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

I don't want to make this very long. So, if you want an explanation of this HTML code, just ask for it in the comments, I will surely help you out.

Once we are done with this, we will move to the views.py file. Now, what we are up to may seem a bit weird and strange if you are new, but we need to just render the index.html template and then let React take care of it. So, the views.py goes like:

# frontend/views.py
from django.shortcuts import render

def index(request, *args, **kwargs):
    return render(request, 'frontend/index.html')
Enter fullscreen mode Exit fullscreen mode

Now, it's time for the urls.py. Before that make sure that you have included the frontend.urls in the urlpatterns of the main-project urls.py file. Again, if you need help, just comment. However, it should look somewhat like this:

# project/urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('app/', include('app.urls')),
    path('', include('frontend.urls'))
]
Enter fullscreen mode Exit fullscreen mode

This is just an example.

Now, time for our frontend's urls.py.

# frontend/urls.py
from django.urls import path
from .views import index

urlpatterns = [
    path('', index),
    # Other URL Patterns...
]
Enter fullscreen mode Exit fullscreen mode

Next, we are supposed to make a React component, and therefore we will create an App.js file in the components directory which kinda goes like this:

import React, { Component } from "react";
import { render } from "react-dom";
// import one other component for simplicity
import Home from "./Home";
// import other components if you need them

export default class App extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div>
        <Home />
      </div>
    );
  }
}

const appDiv = document.getElementById("app");
render(<App />, appDiv);
Enter fullscreen mode Exit fullscreen mode

And now, we just need to import the ./components/App we created just created to the index.js file in the src directory.

// src/index.js
import App from "./components/App";
Enter fullscreen mode Exit fullscreen mode

And now, our entry file imports this file, which runs the code and renders the App.js in the index.html template.

Finally, What we have to do is to make sure that our servers are running properly because we may have done something wrong in this whole long process. Once our server is running fine, we need to run the script that we had put inside of our package.json. So the Webpack module development watch should look at our index.js file. It should see that we're importing App.js. It should bundle it together. It should output something to static front-end and that file should be calling main.js. And then we'll go to the URL endpoint. And now, in the terminal, inside the frontend directory, we should run the development server by typing in:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Finally, make sure to do one thing, which I forget most of the time, eventually, I forgot it even while writing it is that we need to list this frontend Django App in the INSTALLED_APPS in the settings.py file in the main project directory.

# project/settings.py

# ...
INSTALLED_APPS = [
    # ...
    'frontend.apps.FrontendConfig',
]
# ...
Enter fullscreen mode Exit fullscreen mode

That's done. Feel free to comment or DM me, if you face any difficulties.
Have a Nice Day Ahead!!
Thank You!

Top comments (2)

Collapse
 
spaceofmiah profile image
Osazuwa J. Agbonze

Awesome post. Thanks for putting it up.

Should in case anyone encounter this error that i got after running npm run dev

WARNING in DefinePlugin
Conflicting values for 'process.env.NODE_ENV'

1 warning has detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.
Enter fullscreen mode Exit fullscreen mode

you can resolve by setting NODE_ENV in webpack.config.js from JSON.stringify("production") to JSON.stringify("development").

Completely removing NODE_ENV: JSON.stringify("xxxx") also works fine but i'm uncertain as to what impact that would leave the configurations/application and would appreciate if someone could share

Collapse
 
arindam-sahoo profile image
Arindam Sahoo

I suppose it should not cause any problems until and unless you are using any plugins that rely on that.