Skip to content

Commit e5e43d5

Browse files
hyshkafjsj
authored andcommitted
Add a setting to determine skip common chunks behaviour
1 parent 47bae2f commit e5e43d5

File tree

5 files changed

+186
-21
lines changed

5 files changed

+186
-21
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Example</title>
6+
{{ render_bundle('app1', 'js') }}
7+
{{ render_bundle('app2', 'js', skip_common_chunks=False) }}
8+
</head>
9+
10+
<body>
11+
<div id="react-app"></div>
12+
{{ render_bundle('app1', 'js', skip_common_chunks=False) }}
13+
{{ render_bundle('app2', 'js', skip_common_chunks=False) }}
14+
</body>
15+
</html>

tests/app/tests/test_webpack.py

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

530-
def test_skip_common_chunks_djangoengine(self):
531-
"""Test case for deduplication of modules with the django engine."""
532-
self.compile_bundles('webpack.config.skipCommon.js')
533-
534-
django_engine = engines['django']
535-
dups_template = django_engine.from_string(template_code=(
536-
r'{% load render_bundle from webpack_loader %}'
537-
r'{% render_bundle "app1" %}'
538-
r'{% render_bundle "app2" %}')) # type: Template
530+
def _assert_common_chunks_duplicated_djangoengine(self, template=None):
531+
if template is None:
532+
raise TypeError('Django template is a required argument')
539533
request = self.factory.get(path='/')
540534
asset_vendor = (
541535
'<script src="/static/django_webpack_loader_bundles/vendors.js" >'
@@ -546,7 +540,7 @@ def test_skip_common_chunks_djangoengine(self):
546540
asset_app2 = (
547541
'<script src="/static/django_webpack_loader_bundles/app2.js" >'
548542
'</script>')
549-
rendered_template = dups_template.render(
543+
rendered_template = template.render(
550544
context=None, request=request)
551545
used_tags = getattr(request, '_webpack_loader_used_tags', None)
552546

@@ -556,13 +550,20 @@ def test_skip_common_chunks_djangoengine(self):
556550
self.assertEqual(rendered_template.count(asset_app2), 1)
557551
self.assertEqual(rendered_template.count(asset_vendor), 2)
558552

559-
nodups_template = django_engine.from_string(template_code=(
560-
r'{% load render_bundle from webpack_loader %}'
561-
r'{% render_bundle "app1" %}'
562-
r'{% render_bundle "app2" skip_common_chunks=True %}')
563-
) # type: Template
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')
564556
request = self.factory.get(path='/')
565-
rendered_template = nodups_template.render(
557+
asset_vendor = (
558+
'<script src="/static/django_webpack_loader_bundles/vendors.js" >'
559+
'</script>')
560+
asset_app1 = (
561+
'<script src="/static/django_webpack_loader_bundles/app1.js" >'
562+
'</script>')
563+
asset_app2 = (
564+
'<script src="/static/django_webpack_loader_bundles/app2.js" >'
565+
'</script>')
566+
rendered_template = template.render(
566567
context=None, request=request)
567568
used_tags = getattr(request, '_webpack_loader_used_tags', None)
568569

@@ -572,11 +573,48 @@ def test_skip_common_chunks_djangoengine(self):
572573
self.assertEqual(rendered_template.count(asset_app2), 1)
573574
self.assertEqual(rendered_template.count(asset_vendor), 1)
574575

575-
def test_skip_common_chunks_jinja2engine(self):
576-
"""Test case for deduplication of modules with the Jinja2 engine."""
577-
self.compile_bundles('webpack.config.skipCommon.js')
576+
def _assert_common_chunks_duplicated_jinja2engine(self, view=None):
577+
if view is None:
578+
raise TypeError('TemplateView is a required argument')
579+
settings = {
580+
'TEMPLATES': [
581+
{
582+
'BACKEND': 'django_jinja.backend.Jinja2',
583+
'APP_DIRS': True,
584+
'OPTIONS': {
585+
'match_extension': '.jinja',
586+
'extensions': DEFAULT_EXTENSIONS + [_OUR_EXTENSION],
587+
}
588+
},
589+
]
590+
}
591+
asset_vendor = (
592+
'<script src="/static/django_webpack_loader_bundles/vendors.js" >'
593+
'</script>')
594+
asset_app1 = (
595+
'<script src="/static/django_webpack_loader_bundles/app1.js" >'
596+
'</script>')
597+
asset_app2 = (
598+
'<script src="/static/django_webpack_loader_bundles/app2.js" >'
599+
'</script>')
578600

579-
view = TemplateView.as_view(template_name='home-deduplicated.jinja')
601+
with self.settings(**settings):
602+
request = self.factory.get('/')
603+
result = view(request) # type: TemplateResponse
604+
content = result.rendered_content
605+
self.assertIn(asset_vendor, content)
606+
self.assertIn(asset_app1, content)
607+
self.assertIn(asset_app2, content)
608+
self.assertEqual(content.count(asset_vendor), 4)
609+
self.assertEqual(content.count(asset_app1), 2)
610+
self.assertEqual(content.count(asset_app2), 2)
611+
used_tags = getattr(request, '_webpack_loader_used_tags', None)
612+
self.assertIsNotNone(used_tags, msg=(
613+
'_webpack_loader_used_tags should be a property of request!'))
614+
615+
def _assert_common_chunks_not_duplicated_jinja2engine(self, view=None):
616+
if view is None:
617+
raise TypeError('TemplateView is a required argument')
580618
settings = {
581619
'TEMPLATES': [
582620
{
@@ -612,3 +650,104 @@ def test_skip_common_chunks_jinja2engine(self):
612650
used_tags = getattr(request, '_webpack_loader_used_tags', None)
613651
self.assertIsNotNone(used_tags, msg=(
614652
'_webpack_loader_used_tags should be a property of request!'))
653+
654+
def test_skip_common_chunks_djangoengine(self):
655+
"""Test case for deduplication of modules with the django engine."""
656+
self.compile_bundles('webpack.config.skipCommon.js')
657+
658+
django_engine = engines['django']
659+
dups_template = django_engine.from_string(template_code=(
660+
r'{% load render_bundle from webpack_loader %}'
661+
r'{% render_bundle "app1" %}'
662+
r'{% render_bundle "app2" %}')) # type: Template
663+
self._assert_common_chunks_duplicated_djangoengine(dups_template)
664+
665+
nodups_template = django_engine.from_string(template_code=(
666+
r'{% load render_bundle from webpack_loader %}'
667+
r'{% render_bundle "app1" %}'
668+
r'{% render_bundle "app2" skip_common_chunks=True %}')
669+
) # type: Template
670+
self._assert_common_chunks_not_duplicated_djangoengine(nodups_template)
671+
672+
673+
def test_skip_common_chunks_jinja2engine(self):
674+
"""Test case for deduplication of modules with the Jinja2 engine."""
675+
self.compile_bundles('webpack.config.skipCommon.js')
676+
677+
view = TemplateView.as_view(template_name='home-deduplicated.jinja')
678+
self._assert_common_chunks_not_duplicated_jinja2engine(view)
679+
680+
def test_skip_common_chunks_setting_djangoengine(self):
681+
"""Test case for deduplication of modules with the django engine."""
682+
self.compile_bundles('webpack.config.skipCommon.js')
683+
684+
django_engine = engines['django']
685+
dups_template = django_engine.from_string(template_code=(
686+
r'{% load render_bundle from webpack_loader %}'
687+
r'{% render_bundle "app1" %}'
688+
r'{% render_bundle "app2" %}')) # type: Template
689+
self._assert_common_chunks_duplicated_djangoengine(dups_template)
690+
691+
loader = get_loader(DEFAULT_CONFIG)
692+
with patch.dict(loader.config, {"SKIP_COMMON_CHUNKS": True}):
693+
self._assert_common_chunks_not_duplicated_djangoengine(dups_template)
694+
695+
def test_skip_common_chunks_setting_jinja2engine(self):
696+
"""Test case for deduplication of modules with the Jinja2 engine."""
697+
self.compile_bundles('webpack.config.skipCommon.js')
698+
699+
view = TemplateView.as_view(template_name='home-duplicated.jinja')
700+
self._assert_common_chunks_duplicated_jinja2engine(view)
701+
702+
loader = get_loader(DEFAULT_CONFIG)
703+
with patch.dict(loader.config, {"SKIP_COMMON_CHUNKS": True}):
704+
self._assert_common_chunks_not_duplicated_jinja2engine(view)
705+
706+
def test_skip_common_chunks_setting_can_be_overridden_djangoengine(self):
707+
"""Skip common chunks template tag options should take precedent over global setting."""
708+
self.compile_bundles('webpack.config.skipCommon.js')
709+
710+
django_engine = engines['django']
711+
nodups_template = django_engine.from_string(template_code=(
712+
r'{% load render_bundle from webpack_loader %}'
713+
r'{% render_bundle "app1" %}'
714+
r'{% render_bundle "app2" skip_common_chunks=True %}')
715+
) # type: Template
716+
self._assert_common_chunks_not_duplicated_djangoengine(nodups_template)
717+
718+
loader = get_loader(DEFAULT_CONFIG)
719+
with patch.dict(loader.config, {"SKIP_COMMON_CHUNKS": True}):
720+
dups_template = django_engine.from_string(template_code=(
721+
r'{% load render_bundle from webpack_loader %}'
722+
r'{% render_bundle "app1" %}'
723+
r'{% render_bundle "app2" skip_common_chunks=False %}')) # type: Template
724+
self._assert_common_chunks_duplicated_djangoengine(dups_template)
725+
726+
def test_skip_common_chunks_setting_can_be_overridden_jinja2engine(self):
727+
"""Test case for deduplication of modules with the Jinja2 engine."""
728+
self.compile_bundles('webpack.config.skipCommon.js')
729+
730+
view = TemplateView.as_view(template_name='home-deduplicated.jinja')
731+
self._assert_common_chunks_not_duplicated_jinja2engine(view)
732+
733+
loader = get_loader(DEFAULT_CONFIG)
734+
with patch.dict(loader.config, {"SKIP_COMMON_CHUNKS": True}):
735+
view = TemplateView.as_view(template_name='home-duplicated-forced.jinja')
736+
self._assert_common_chunks_duplicated_jinja2engine(view)
737+
738+
def test_skip_common_chunks_missing_config(self):
739+
self.compile_bundles('webpack.config.skipCommon.js')
740+
741+
loader = get_loader(DEFAULT_CONFIG)
742+
# remove SKIP_COMMON_CHUNKS from config completely to test backward compatibility
743+
skip_common_chunks = loader.config.pop('SKIP_COMMON_CHUNKS')
744+
745+
django_engine = engines['django']
746+
dups_template = django_engine.from_string(template_code=(
747+
r'{% load render_bundle from webpack_loader %}'
748+
r'{% render_bundle "app1" %}'
749+
r'{% render_bundle "app2" %}')) # type: Template
750+
self._assert_common_chunks_duplicated_djangoengine(dups_template)
751+
752+
# return removed key
753+
loader.config['SKIP_COMMON_CHUNKS'] = skip_common_chunks

webpack_loader/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
'IGNORE': [r'.+\.hot-update.js', r'.+\.map'],
1717
'LOADER_CLASS': 'webpack_loader.loader.WebpackLoader',
1818
'INTEGRITY': False,
19+
'SKIP_COMMON_CHUNKS': False,
1920
}
2021
}
2122

webpack_loader/templatetags/webpack_loader.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
@register.simple_tag(takes_context=True)
1717
def render_bundle(
1818
context, bundle_name, extension=None, config='DEFAULT', suffix='',
19-
attrs='', is_preload=False, skip_common_chunks=False):
19+
attrs='', is_preload=False, skip_common_chunks=None):
20+
if skip_common_chunks is None:
21+
skip_common_chunks = utils.get_skip_common_chunks(config)
2022
tags = utils.get_as_tags(
2123
bundle_name, extension=extension, config=config, suffix=suffix,
2224
attrs=attrs, is_preload=is_preload)

webpack_loader/utils.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@ def get_loader(config_name):
2828
return _loaders[config_name]
2929

3030

31+
def get_skip_common_chunks(config_name):
32+
loader = get_loader(config_name)
33+
# The global default is currently False, whenever that is changed, change
34+
# this fallback value as well which is present to provide backwards
35+
# compatibility.
36+
return loader.config.get('SKIP_COMMON_CHUNKS', False)
37+
38+
3139
def _filter_by_extension(bundle, extension):
3240
'''Return only files with the given extension'''
3341
for chunk in bundle:

0 commit comments

Comments
 (0)