I am using Angular 4 for client side/frontend and using django 1.11 for backend. I edited .angular-cli.json to redirect the bundles output directory to django app assets
./.angular-cli.json
{
...
"apps":[
..,
"outDir": "django_app/assets/webpack_bundles/",
....
],
...
}
when building ng build --dev
(which for development environment), will create the webpack bundles under assets
./django_app/assets/webpack_bundles
django_app/
- assets/
-- webpack_bundles/
--- inline.bundle.js
--- main.bundle.js
--- polyfills.bundle.js
--- vendor.bundle.js
then running python3 manage.py collectstatic
to migrate in static files and to import it in django templates
./django_app/templates/sample.html
{%load static %}
<script src="{% static 'webpack_bundles/inline.bundle.js' %}"></script>
<script src="{% static 'webpack_bundles/polyfills.bundle.js' %}"></script>
<script src="{% static 'webpack_bundles/vendor.bundle.js' %}"></script>
<script src="{% static 'webpack_bundles/main.bundle.js' %}"></script>
The question is, how can I load webpack bundles on a django templates if building for production ng build --prod
? Which will create bundles in minified version and with hash for caching purposes.
./django_app/assets/webpack_bundles
django_app/
- assets/
-- webpack_bundles/
--- inline.[hash].bundle.js
--- main.[hash].bundle.js
--- polyfills.[hash].bundle.js
--- vendor.[hash].bundle.js
Tried the solution of having ng build --prod --output-hashing none
, but this is not a best practice because of caching. Tried using django_webpack_loader
, but it is not applicable for angular 4 webpack.config.js
I'm running into the same issue. I have a fix I feel pretty mediocre about.
In settings.py:
def first(pair):
return pair[0]
def load_webpack_bundle(static_folder):
"""
Okay this is gross, but the alternative is hacking apart the angular.json
build script so I can use an existing loader, which is itself kind
of gross and makes some assumptions it'd be work to satisfy.
The output is a dictionary of dictionaries: {extension:
{file-name-prefix: path-to-file-in-static-dir}.
This assumes you only have a single static file dir to checkout, but if
you had more I think it would be starightforward to add them.
"""
webpack_built_files = {}
stats = os.path.join(static_folder, 'bundle', 'stats.json')
if os.path.exists(stats):
with open(stats) as f:
stats = json.load(f)
files = ['bundle/' + m['name'] for m in stats['assets']]
by_extension = [(f.split('.').pop(), f) for f in files]
for k, v in itertools.groupby(
sorted(by_extension, key=first), key=first
):
v = [i for i in v]
webpack_built_files[k] = {
r[1].split('.')[0].split('/').pop(): r[1] for r in v
}
return webpack_built_files
WEBPACK_BUILT_FILES = load_weback_bundle(os.join(*PATH_TO_YOUR_DIST_DIR))
In angular.json, under build add for both your dev and production settings "statsJson": true,
In whatever views are serving your angular app, add the following context:
'STATIC': settings.WEBPACK_BUILT_FILES
In you template:
{% load static %}
<!doctype html>
<html>
<head>
<!-- ... -->
<link href="{{STATIC.css.styles}}" rel="stylesheet">
</head>
<body>
<app-root>Loading...</app-root>
<!-- Order matters: if you don't have runtime and polyfill before main, you will get a cryptic exception about zone.js not being incldued -->
<script type="application/javascript" src="{% static STATIC.js.runtime %}"></script>
<script type="application/javascript" src="{% static STATIC.js.polyfills %}"></script>
<script type="application/javascript" src="{% static STATIC.js.main %}"></script>
</html>
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.