Skip to content

Commit b4ba26a

Browse files
hyshkafjsj
authored andcommitted
Add a setting to configure skip common chunks behaviour globally
You can now specify a 'SKIP_COMMON_CHUNKS' setting globally for each Webpack configuration. This will perform the same 'skip_common_chunks' logic from the 'render_bundle' template tag without having to add a parameter to every tag. To maintain backwards compatibility we default to 'False' and allow common chunks to be rendered to the HTML document as script tags. In the future, it will be easy to change this default behaviour if desired. I've added test coverage to ensure that the global setting can be override by the existing template tag parameter and that we maintain backwards compatibility.
1 parent e5e43d5 commit b4ba26a

File tree

3 files changed

+42
-21
lines changed

3 files changed

+42
-21
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ The `STATS_FILE` parameter represents the output file produced by `webpack-bundl
111111

112112
- `LOADER_CLASS` is the fully qualified name of a python class as a string that holds the custom webpack loader. This is where behavior can be customized as to how the stats file is loaded. Examples include loading the stats file from a database, cache, external url, etc. For convenience, `webpack_loader.loader.WebpackLoader` can be extended. The `load_assets` method is likely where custom behavior will be added. This should return the stats file as an object.
113113

114+
- `SKIP_COMMON_CHUNKS` is a flag which prevents already generated chunks from being included again in the same page. This should only happen if you use more than one entrypoint per Django template (multiple `render_bundle` calls). By enabling this, you can get the same default behavior of the [HtmlWebpackPlugin](https://webpack.js.org/plugins/html-webpack-plugin/). The same caveats apply as when using `skip_common_chunks` on `render_bundle`, see that section below for more details.
115+
114116
Here's a simple example of loading from an external url:
115117

116118
```py
@@ -239,7 +241,7 @@ The public path is based on `webpack.config.js` [output.publicPath](https://webp
239241
Please note that this approach will use the original asset file, and not a post-processed one from the Webpack pipeline, in case that file had gone through such flow (i.e.: You've imported an image on the React side and used it there, the file used within the React components will probably have a hash string on its name, etc. This processed file will be different than the one you'll grab with `webpack_static`).
240242

241243
### Use `skip_common_chunks` on `render_bundle`
242-
You can use the parameter `skip_common_chunks=True` to specify that you don't want an already generated chunk be included again in the same page. This should only happen if you use more than one entrypoint per Django template (multiple `render_bundle` calls). By using `skip_common_chunks=True`, you can get the same default behavior of the [HtmlWebpackPlugin](https://webpack.js.org/plugins/html-webpack-plugin/).
244+
You can use the parameter `skip_common_chunks=True` or `skip_common_chunks=False` to override the global `SKIP_COMMON_CHUNKS` setting for a specific bundle.
243245

244246
In order for this option to work, `django-webpack-loader` requires the `request` object to be in the context, to be able to keep track of the generated chunks.
245247

tests/app/tests/test_webpack.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -527,9 +527,13 @@ def test_emits_warning_on_no_request_in_jinja2engine(self):
527527
_warn_mock.assert_not_called()
528528
_warn_mock.reset_mock()
529529

530-
def _assert_common_chunks_duplicated_djangoengine(self, template=None):
531-
if template is None:
532-
raise TypeError('Django template is a required argument')
530+
def _assert_common_chunks_duplicated_djangoengine(self, template):
531+
"""
532+
Verify that any common chunks between two bundles are duplicated in
533+
the HTML markup.
534+
535+
:param template: A Django template instance
536+
"""
533537
request = self.factory.get(path='/')
534538
asset_vendor = (
535539
'<script src="/static/django_webpack_loader_bundles/vendors.js" >'
@@ -550,9 +554,13 @@ def _assert_common_chunks_duplicated_djangoengine(self, template=None):
550554
self.assertEqual(rendered_template.count(asset_app2), 1)
551555
self.assertEqual(rendered_template.count(asset_vendor), 2)
552556

553-
def _assert_common_chunks_not_duplicated_djangoengine(self, template=None):
554-
if template is None:
555-
raise TypeError('Django template is a required argument')
557+
def _assert_common_chunks_not_duplicated_djangoengine(self, template):
558+
"""
559+
Verify that any common chunks between two bundles are not duplicated in
560+
the HTML markup.
561+
562+
:param template: A Django template instance
563+
"""
556564
request = self.factory.get(path='/')
557565
asset_vendor = (
558566
'<script src="/static/django_webpack_loader_bundles/vendors.js" >'
@@ -573,9 +581,13 @@ def _assert_common_chunks_not_duplicated_djangoengine(self, template=None):
573581
self.assertEqual(rendered_template.count(asset_app2), 1)
574582
self.assertEqual(rendered_template.count(asset_vendor), 1)
575583

576-
def _assert_common_chunks_duplicated_jinja2engine(self, view=None):
577-
if view is None:
578-
raise TypeError('TemplateView is a required argument')
584+
def _assert_common_chunks_duplicated_jinja2engine(self, view):
585+
"""
586+
Verify that any common chunks between two bundles are duplicated in
587+
the HTML markup.
588+
589+
:param view: A Django TemplateView instance
590+
"""
579591
settings = {
580592
'TEMPLATES': [
581593
{
@@ -612,9 +624,13 @@ def _assert_common_chunks_duplicated_jinja2engine(self, view=None):
612624
self.assertIsNotNone(used_tags, msg=(
613625
'_webpack_loader_used_tags should be a property of request!'))
614626

615-
def _assert_common_chunks_not_duplicated_jinja2engine(self, view=None):
616-
if view is None:
617-
raise TypeError('TemplateView is a required argument')
627+
def _assert_common_chunks_not_duplicated_jinja2engine(self, view):
628+
"""
629+
Verify that any common chunks between two bundles are not duplicated in
630+
the HTML markup.
631+
632+
:param view: A Django TemplateView instance
633+
"""
618634
settings = {
619635
'TEMPLATES': [
620636
{
@@ -651,8 +667,8 @@ def _assert_common_chunks_not_duplicated_jinja2engine(self, view=None):
651667
self.assertIsNotNone(used_tags, msg=(
652668
'_webpack_loader_used_tags should be a property of request!'))
653669

654-
def test_skip_common_chunks_djangoengine(self):
655-
"""Test case for deduplication of modules with the django engine."""
670+
def test_skip_common_chunks_templatetag_djangoengine(self):
671+
"""Test case for deduplication of modules with the django engine via the render_bundle template tag."""
656672
self.compile_bundles('webpack.config.skipCommon.js')
657673

658674
django_engine = engines['django']
@@ -670,15 +686,15 @@ def test_skip_common_chunks_djangoengine(self):
670686
self._assert_common_chunks_not_duplicated_djangoengine(nodups_template)
671687

672688

673-
def test_skip_common_chunks_jinja2engine(self):
674-
"""Test case for deduplication of modules with the Jinja2 engine."""
689+
def test_skip_common_chunks_templatetag_jinja2engine(self):
690+
"""Test case for deduplication of modules with the Jinja2 engine via the render_bundle template tag."""
675691
self.compile_bundles('webpack.config.skipCommon.js')
676692

677693
view = TemplateView.as_view(template_name='home-deduplicated.jinja')
678694
self._assert_common_chunks_not_duplicated_jinja2engine(view)
679695

680696
def test_skip_common_chunks_setting_djangoengine(self):
681-
"""Test case for deduplication of modules with the django engine."""
697+
"""The global setting should default to False and deduplicate chunks without changing the render_bundle template tag."""
682698
self.compile_bundles('webpack.config.skipCommon.js')
683699

684700
django_engine = engines['django']
@@ -693,7 +709,7 @@ def test_skip_common_chunks_setting_djangoengine(self):
693709
self._assert_common_chunks_not_duplicated_djangoengine(dups_template)
694710

695711
def test_skip_common_chunks_setting_jinja2engine(self):
696-
"""Test case for deduplication of modules with the Jinja2 engine."""
712+
"""The global setting should default to False and deduplicate chunks without changing the render_bundle template tag."""
697713
self.compile_bundles('webpack.config.skipCommon.js')
698714

699715
view = TemplateView.as_view(template_name='home-duplicated.jinja')
@@ -704,7 +720,7 @@ def test_skip_common_chunks_setting_jinja2engine(self):
704720
self._assert_common_chunks_not_duplicated_jinja2engine(view)
705721

706722
def test_skip_common_chunks_setting_can_be_overridden_djangoengine(self):
707-
"""Skip common chunks template tag options should take precedent over global setting."""
723+
"""The skip common chunks template tag parameters should take precedent over the global setting."""
708724
self.compile_bundles('webpack.config.skipCommon.js')
709725

710726
django_engine = engines['django']
@@ -724,7 +740,7 @@ def test_skip_common_chunks_setting_can_be_overridden_djangoengine(self):
724740
self._assert_common_chunks_duplicated_djangoengine(dups_template)
725741

726742
def test_skip_common_chunks_setting_can_be_overridden_jinja2engine(self):
727-
"""Test case for deduplication of modules with the Jinja2 engine."""
743+
"""The skip common chunks template tag parameters should take precedent over the global setting."""
728744
self.compile_bundles('webpack.config.skipCommon.js')
729745

730746
view = TemplateView.as_view(template_name='home-deduplicated.jinja')
@@ -736,6 +752,7 @@ def test_skip_common_chunks_setting_can_be_overridden_jinja2engine(self):
736752
self._assert_common_chunks_duplicated_jinja2engine(view)
737753

738754
def test_skip_common_chunks_missing_config(self):
755+
"""If the setting is not present we should default to allowing common chunks."""
739756
self.compile_bundles('webpack.config.skipCommon.js')
740757

741758
loader = get_loader(DEFAULT_CONFIG)

webpack_loader/config.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
'IGNORE': [r'.+\.hot-update.js', r'.+\.map'],
1717
'LOADER_CLASS': 'webpack_loader.loader.WebpackLoader',
1818
'INTEGRITY': False,
19+
# Whenever the global setting for SKIP_COMMON_CHUNKS is changed, please
20+
# update the fallback value in get_skip_common_chunks (utils.py).
1921
'SKIP_COMMON_CHUNKS': False,
2022
}
2123
}

0 commit comments

Comments
 (0)