简体   繁体   中英

How to load the webpack bundles created in 'ng build --prod' in django templates?

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.

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