Stack:

Angular 6, Django 2.1

Problem:

How to pass hash to Django index template when publishing an angular production app? Folder structure looks like this:

├── ui
│   ├── angular.json
│   ├── karma.conf.js
│   ├── node_modules
│   ├── package.json
│   ├── src
│   ├── ...
└── django_project
    ├── manage.py
    ├── core
    │   ├── settings.py
    ├── site
    │   ├── templates
    │   │   ├── index.html
    ├── static
    │   ├── dist
    │   │   ├── stats.json
    │   │   ├── common.<hash>.js
    │   │   ├── main.<hash>.js
    │   │   ├── polyfills.<hash>.js
    │   │   ├── runtime.<hash>.js
    │   │   ├── scripts.<hash>.js    

index.html is managed by Django. Rest of static (scripts, css, js) is handled by angular-cli. Following ng script publishes angular production scripts:

ng build --prod --build-optimizer --progress --stats-json --aot --vendor-chunk=true --base-href=/static/dist/ --deploy-url=/static/dist/
  • Option --stats-json generates a 'stats.json' file. Stats file is loaded in project settings to extract generated script names.

My Solution:

settings.py

DIST_DIR = os.path.join(STATICFILES_DIRS[0], 'dist')
def load_stats_json():
with open(os.path.join(DIST_DIR, 'stats.json'), 'r') as file:
dict_object = json.loads(file.read())['assetsByChunkName'] or {}
return {k: ('dist/' + v) for k, v in dict_object.items()}


views.py

def home(request):
    return render(request, 'index.html', settings.ANGULAR_STATS)

index.html

<link rel="stylesheet" href="{% static styles %}">
...
<script type="text/javascript" src="{% static runtime %}"></script>
<script type="text/javascript" src="{% static polyfills %}"></script>
<script type="text/javascript" src="{% static scripts %}"></script>
<script type="text/javascript" src="{% static vendor %}"></script>
<script type="text/javascript" src="{% static main %}"></script></body>
...

And that's how chunk assets are loaded into Django!

...

I have one problem though. I'd like for ANGULAR_STATS to be loaded once on server startup, but settings.py is loaded once per every process. Possible solution is to call load_stats_json in apps.py and to setup ANGULAR_STATS on ready method call.