I am trying to deploy on Heroku my app built with Django 2, DRF and Angular 6, and struggling to get the static files of my Angular app served. I am using WhitheNoise for both development environment and on Heroku. The structure of the project is as follows:
my_project/
|-frontend/
| |- dist/
| |- ...
|-myproject/
| |-settings/
| | |- __init.py
| | |- base.py
| | |- prod.py
| | |- dev.py
| |- __init__.py
| |- urls.py
| |- views.py
| |- wsgi.py
|-other_app1/
| |- ...
|-other_app2/
| |- ...
|-staticfiles/
| |-....
|-manage.py
|-Procfile
|-requirements.txt
I have configured Heroku in such a way that every time my app is deployed, my angular app is built, so the static files are generated in frontend/dist/, then collectstatic is run and copies them to my static files folder in the root of my project. My settings are:
ANGULAR_APP_DIR = os.path.join(BASE_DIR, 'frontend/dist')
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = '/static/'
STATICFILES_DIRS = [
('frontend', os.path.join(ANGULAR_APP_DIR)),
]
This works fine and collects all the files of my angular app inside staticfiles/ withing a folder called frontend/
My problem is that now I am trying to serve the index.html file that is located in staticfiles/frontend and I cannot make it work:
urls.py
urlpatterns = [
path('', HomePageView.as_view()), #first one
# .... Other urls
]
views.py
from django.views import static
# Serves the index page
class HomePageView(TemplateView):
def get(self, request, **kwargs):
return static.serve(request,'index.html', 'staticfiles')
This finds and serves the index.html file, but fails to serve successfully the rest of necessary js files for my app to run (polyfills, main, styles...), as the '/static/' is not appended automatically to the url that requests them. Does someone know how I can tell Django or Heroku to find them under the staticfiles/frontend folder?
The generated index.html looks like this:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>My Angular Project</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="stylesheet" href="styles.578ada0b0e3742b4b4bb.css"></head>
<body class="with-top-navbar">
<app-root></app-root>
<script type="text/javascript" src="runtime.92d800a8cdfd75f49eae.js"></script>
<script type="text/javascript" src="polyfills.7ee4ee2275a8c5d5ea6f.js"></script>
<script type="text/javascript" src="main.4aeccc46b72bbab58fd0.js"></script></body>
</html>
And the output of my console is:
[29/Jun/2018 13:31:30] "GET / HTTP/1.1" 200 638
Not Found: /styles.578ada0b0e3742b4b4bb.css
Not Found: /runtime.92d800a8cdfd75f49eae.js
[29/Jun/2018 13:31:30] "GET /styles.578ada0b0e3742b4b4bb.css HTTP/1.1" 404 2353
Not Found: /polyfills.7ee4ee2275a8c5d5ea6f.js
Not Found: /main.4aeccc46b72bbab58fd0.js
[29/Jun/2018 13:31:30] "GET /polyfills.7ee4ee2275a8c5d5ea6f.js HTTP/1.1" 404 2359
[29/Jun/2018 13:31:30] "GET /runtime.92d800a8cdfd75f49eae.js HTTP/1.1" 404 2353
[29/Jun/2018 13:31:30] "GET /main.4aeccc46b72bbab58fd0.js HTTP/1.1" 404 2344
Not Found: /styles.578ada0b0e3742b4b4bb.css
[29/Jun/2018 13:31:32] "GET /styles.578ada0b0e3742b4b4bb.css HTTP/1.1" 404 2353
Not Found: /runtime.92d800a8cdfd75f49eae.js
[29/Jun/2018 13:31:32] "GET /runtime.92d800a8cdfd75f49eae.js HTTP/1.1" 404 2353
Not Found: /polyfills.7ee4ee2275a8c5d5ea6f.js
[29/Jun/2018 13:31:32] "GET /polyfills.7ee4ee2275a8c5d5ea6f.js HTTP/1.1" 404 2359
Not Found: /main.4aeccc46b72bbab58fd0.js
[29/Jun/2018 13:31:32] "GET /main.4aeccc46b72bbab58fd0.js HTTP/1.1" 404 2344
Also, please note that I do not want to edit manually the generated index.html nor place it somewhere else, as this would change my deployment workflow.
In addition, I know that django.views.statics.serve is not appropriate for production, so tips are also welcome if you know how to serve this file in some other way
Thanks!