简体   繁体   中英

django-webpack-loader not rendering react app using react-app-rewired

I'm working on tying my react(16.6.3) and Django(2.0) apps together. Right now I'm just working to get the dev server working and will focus on production later. I've been following a handful of guides on this process, but they're all a little different (and most seem outdated) and I haven't been able to find the right combination to get this working. My ultimate goal is that I'd like to be able to run the dev servers from 1 terminal window.

I'm using react-app-rewired because I'd like to not have to eject. My understanding is that it's more desirable to not eject rather than have to manually configure all of the Webpack configs. This may especially be true for me as I'm still learning react/webpack.

Its my understanding that once this is configured I just need to run the Django server and it should display my app. I'm not running collectstatic or any npm start or build commands.

Here's what I have configured:

base.py

...    
STATICFILES_DIRS = [
        # os.path.join(os.path.join(BASE_DIR, 'frontend'), 'build', 'static')
        os.path.join(BASE_DIR, "frontend", "build", "static"),
    ]
...

local.py

...
WEBPACK_LOADER = {
    "DEFAULT": {
        "CACHE": not DEBUG,
        "BUNDLE_DIR_NAME": "frontend/build/static/",  # must end with slash
        "STATS_FILE": os.path.join(BASE_DIR, "frontend", "build", "webpack-stats.json"),
    }
}
...

config-overrides.js

var BundleTracker = require('webpack-bundle-tracker');

module.exports = {
  webpack: (config, env) => {

    config.plugins.push(
      new BundleTracker({
        path: __dirname,
        filename: './build/webpack-stats.json'
      }),
    );

    return config;
  },
};

main.html

{ % load render_bundle from webpack_loader % }

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Django + React CRUD</title>
  </head>
  <body>
    <div id="root">
     This is where React will be mounted
    </div>
    { % render_bundle 'main' % }
  </body>
</html>

urls.py

from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'', include('api.urls')),
    path(r'', TemplateView.as_view(template_name="main.html"))
]

With this configuration, and the Django server running, when I navigate to localhost:8000 all I see is a basic page:

在此处输入图片说明

Project Structure:

.
├── api
│   ├── __init__.py
│   ├── __pycache__
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   ├── models.py
│   ├── serializers.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── financeApp
│   ├── __init__.py
│   ├── __pycache__
│   └── templates
├── build
│   └── webpack-stats.json
├── config
│   ├── __init__.py
│   ├── __pycache__
│   ├── settings
│   ├── urls.py
│   └── wsgi.py
├── database20181022.json
├── db.sqlite3
├── docker-compose-dev.yml
├── docker-compose.yml
├── docker_compose
│   ├── django
│   ├── nginx
│   ├── node
│   └── postgres
├── frontend
│   ├── README.md
│   ├── build
│   ├── config-overrides.js
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── package0.json
│   ├── public
│   └── src
├── manage.py
├── requirements
│   ├── base.txt
│   ├── local.txt
│   └── production.txt
├── static
│   ├── builds
│   ├── builds-development
│   └── js
├── templates
    └── main.html

Django will not know what to serve. You need to build the app and then serve the built app with django as static.

Alternatively, while developing, serve the react app using npm start run , and Django separately with python manage.py runserver . Not sure what interdependencies you have between the two systems, but you should be able to dynamically specify the routing between npm/django based on the port number.

For production, serving of the assets should be done with a dedicated webserver (eg. Nginx) and routing established so that Nginx acts as a reverse proxy for routing to Django endpoints (eg an API).


With your current approach, this line below is trying to get Django to render the html file using Django templating, rather than react templating so you are getting the wrong output.

TemplateView.as_view(template_name="main.html")

You must either build the source so that these templates are resolved by react, or serve the react code through npm.

While it is possible to serve through django, but it is much more straightforward to serve react and django separately. A benefit of this way is that you have decoupled the front end (react) from the back end (django) and if you make changes to either, you only have to restart that service (front or back end)

Actually this is a syntax-related issue, the Django tags syntax looks like {% tag %} instead of { % tag % } (no space between the curly bracket and percentage sign).

For more information, please refer to the Django template language .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM