Django-Frontendapp, React, Webpack
This article follows up on Part 2 of my Full Stack series, where we finished with our Django/DRF setup.
Architecture:
Before we extend our project with React, I want to mention, that there are multiple ways how to make React work with Django. For me, there 3 obvious options:
- Standalone React + Standalone Django
- Standalone Django + React as a SPA in a Django-App
- Standalone Django + Mix React into Django-Templates
I tried 1&2 and choose the latter, because it comes with benefits I could not leave behind in my small sized project. It will load the bundle produced by webpack within a single plain HTML Template. In comparison to solution 1, this makes it a lot easier to manage authorization between our Back- and Front-End. However, you will also loose at some points like server-side rendering (Django doesn’t understand JS) and seperation of concerns.
Django-Frontendapp
Since we proceed with solution 2 we need an Django-App, where we nest React. Same procedure as we created our backendapp
, go to our Django root and use
$ django-admin startapp frontendapp
So our Django root will have this structure
.
├── backend
├── backendapp
├── frontendapp
├── manage.py
├── db.sqlite3
└── requirements.txt
and don’t forget to add our frontendapp to INSTALLED_APPS in backend/settings.py
Now create a folder for our React bundle, components and static files
$ mkdir -p ./frontendapp/src/components
$ mkdir -p ./frontendapp/{static,templates}/frontend
These folders have the following function
frontendapp/src/components/
: Create our React components herefrontendapp/static/frontend/
: The place where will tell webpack to output the main.js bundlefrontendapp/templates/frontend/
: We will place the bare template, which will include our main.js bundle
Now create our template at frontendapp/temlates/frontend/index.html
See the divison id="react-app"
, where we will hook up our React bundle.
Now include a simple view in our frontendapp/views.py
to render our bare template (Django will per default search for our template at frontendapp/templates/
)
create frontendapp/urls.py
and link to our new view
and finally include our frontendapp
routes to our backend/urls.py
Now (restart the dev-server if stopped) open http://localhost:8000
. If everything went fine, you should see an empty page with the titledjango-rest-react-redux
(compare at index.html
).
React, Webpack
We finished to setup the Django-App, where we nest React. Now it’s time for some JS groundwork.
Tools I use : Atom (read here) + Chrome with React-Dev-Tools/Redux-Dev-Tools (they are a blessing 🙏)
Load and install npm
and Node
here if necessary. Check with
$ npm -v
6.4.1
$ Node -v
v8.12.0
Now navigate to our Django root, we initialize npm
here because for any review of our project it should be visible at root, that there is some JS stuff happening here. So, initialize with
$ npm init -y
install webpack and webpack-cli
$ npm i webpack webpack-cli --save-dev
install Babel, necessary presets and a plugin for ES6
$ npm i @babel/core babel-loader @babel/preset-env @babel/preset-react babel-plugin-transform-class-properties --save-dev
tell Babel, that we will use the presets and plugins with a config file .babelrc
and now create a webpack.config.js
for setting babel-loader
and finally install React
$ npm i react react-dom prop-types --save
Now we can create our entrypoint for webpack to bundle our React-app. Therefore, create frontendapp/src/index.jsx
with a hook to our react-app
division in our template.
Now we have to tell webpack where our new entrypoint lies and where it should output our bundle within webpack.config.js
:
And edit the npm scripts in package.json
:
If we now use npm run dev
webpack will generate a bundle starting at our index.js
and stores it in frontendapp/static/frontend
. The only thing left is tell our template to use our bundle. The easy way would be to use the template-tag{% load static %}
as following in our template:
It will evaluate to frontendapp/static/frontend/main.js
. If everything went fine, you can now refresh http://127.0.0.1:8000/ and you should see our “Hello, World!”, the sign of life of our react-bundle!.
We finish with the following project structure at root:
.
├── .git
├── .python-version
├── README.md
├── backend
│ ├── .babelrc
│ ├── backend
│ ├── backendapp
│ ├── frontendapp
│ ├── manage.py
│ ├── node_modules
│ ├── package-lock.json
│ ├── package.json
│ ├── requirements.txt
│ └── webpack.config.js
│ ├── db.sqlite3
└── virtual-env-blueprint
In the next part we config a more comfortable way to develop React within Django and include Redux to our project! (Link)