I'm using Django 4 and wish to integrate a ReactJS application within the Django framework.
I chose to use the exact approach here to start and installed it identically as outlined.
Here's a list of the installed components and versions:
├── @babel/core@7.20.12
├── @babel/preset-env@7.20.2
├── @babel/preset-react@7.18.6
├── babel-loader@9.1.2
├── clean-webpack-plugin@4.0.0
├── css-loader@6.7.3
├── react-dom@18.2.0
├── react@18.2.0
├── style-loader@3.3.1
├── webpack-bundle-tracker@0.4.3
├── webpack-cli@5.0.1
└── webpack@5.75.0
I do not want to post all of my code here since it is 100% identical to the code in the link above.
Unfortunately, I'm receiving a strange error in the console:
GET http://127.0.0.1:8001/frontend/static/frontend/frontend-dc3188e75be82e0a01e0.js net::ERR_ABORTED 404 (Not Found)
127.0.0.1/:1 Refused to execute script from 'http://127.0.0.1:8001/frontend/static/frontend/frontend-dc3188e75be82e0a01e0.js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.
This appears to be related to the path, but the referenced JS filename is spelled correctly and exists at the exact referenced path.
The server console also displays a similar error:
Not Found: /frontend/static/frontend/frontend-dc3188e75be82e0a01e0.js
Thank you for the feedback. This is how I ultimately performed this integration entirely using a combination of online tutorials, the feedback here and the github repo for django-webpack-loader.
Please see the comment at the very bottom for details on resolving the path issue with DigitalOcean Spaces.
Keep in mind this approach below eliminates a lot of the unnecessary steps and ensures the latest versions of the software are used. References are below.
If React and React-Dom are not already installed into your environment, start here:
npm install react react-dom
A: Setup the Django App and Dependencies
python manage.py startapp frontend
INSTALLED_APPS = [
'frontend',
...
]
Create the templates folder for the frontend app. In my case, my Templates directory is in the root of the project, so under the folder I added 'frontend': ./templates/frontend
Create the template in the newly created frontend folder: ./templates/frontend/index.html
Add the following into the index.html, which contains Django tags to use later for rendering the bundle:
<!DOCTYPE html>
{% load render_bundle from webpack_loader %}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My Site</title>
</head>
<body>
<div id="app"></div>
<p>hello</p>
{% render_bundle 'frontend' %}
</body>
</html>
from django.shortcuts import render
def index(request):
return render(request, 'frontend/index.html')
path('', include('frontend.urls'))
path('', views.index)
python manage.py runserver
B: Install React & Babel
npm init -y
npm install --save-dev @babel/core
npm install --save-dev @babel/preset-env @babel/preset-react
{
"presets": ["@babel/preset-env", "@babel/preset-react"]
}
C: Install & Configure Webpack
npm install --save-dev webpack webpack-cli webpack-bundle-tracker babel-loader css-loader style-loader clean-webpack-plugin
const path = require('path');
const webpack = require('webpack');
const BundleTracker = require('webpack-bundle-tracker');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
context: __dirname,
entry: {
frontend: './frontend/src/index.js',
},
output: {
path: path.resolve('./frontend/static/frontend/'),
filename: '[name]-[hash].js',
publicPath: 'static/frontend/',
},
plugins: [
new CleanWebpackPlugin(),
new BundleTracker({ filename: './webpack-stats.json' })
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
}
{
...,
"scripts": {
...,
"dev": "webpack --config webpack.config.js --watch --mode development",
"build": "webpack --config webpack.config.js --mode production"
}
}
C: Create a basic React APP for testing
In the frontend app folder, create a folder called src.
In the src folder, create an App.js file. Be sure to follow the capitalization. And, add the following to it:
import React from 'react'
const App = () => {
return (
<div>Hello, World!</div>
)
}
export default App
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(
<App />,
document.getElementById('app')
)
D: Install Webpack Loader & Configure
pip install django-webpack-loader
INSTALLED_APPS = (
...
'webpack_loader',
...
)
WEBPACK_LOADER = {
'DEFAULT': {
'CACHE': not DEBUG,
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
'POLL_INTERVAL': 0.1,
'IGNORE': [r'.+\.hot-update.js', r'.+\.map'],
}
}
If you receive an error related to DEBUG, check the available options in the django-webpack-loader instructions (see below for link).
E: Compile the frontend asset files and test
If you commented out the django tags in step A9, remove the comment before proceeding.
Run the following command:
npx webpack --config webpack.config.js --watch
python manage.py runserver
References: Outdated Tutorial https://dev.to/zachtylr21/how-to-serve-a-react-single-page-app-with-django-1a1l
django-webpack-loader repo https://github.com/django-webpack/django-webpack-loader