Skip to content

Commit 043f506

Browse files
committed
Improve get_files support for skip_common_chunks, avoid changing public API for get_as_tags
1 parent 1792e80 commit 043f506

File tree

10 files changed

+119
-18
lines changed

10 files changed

+119
-18
lines changed

tests/app/settings.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@
119119
'BUNDLE_DIR_NAME': 'django_webpack_loader_bundles/',
120120
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats-app2.json'),
121121
},
122+
'GET_FILES': {
123+
'CACHE': False,
124+
'BUNDLE_DIR_NAME': 'django_webpack_loader_bundles/',
125+
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats-getFiles.json'),
126+
},
122127
'NO_IGNORE_APP': {
123128
'IGNORE': [],
124129
},

tests/app/templates/home.html

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% load render_bundle webpack_static from webpack_loader %}
1+
{% load render_bundle webpack_static get_files from webpack_loader %}
22
<!DOCTYPE html>
33
<html>
44
<head>
@@ -11,8 +11,18 @@
1111
<body>
1212
<img src="{% webpack_static 'my-image.png' %}"/>
1313
<img src="{% webpack_static 'my-image.png' 'APP2'%}"/>
14+
1415
<div id="react-app"></div>
16+
1517
{% render_bundle 'main' 'js' attrs='async charset="UTF-8"'%}
1618
{% render_bundle 'app2' 'js' config='APP2' %}
19+
20+
{% render_bundle 'getFiles' 'css' config='GET_FILES' %}
21+
{% get_files 'getFiles' 'css' config='GET_FILES' skip_common_chunks=True as other_files %}
22+
{% for css_file in other_files %}
23+
<li>{{ css_file.url }}</li>
24+
{% empty %}
25+
<li>All from getFiles already rendered</li>
26+
{% endfor %}
1727
</body>
1828
</html>

tests/app/templates/only_files.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<script>
33

44
{% get_files 'main' 'css' as main_css_files %}
5-
{% get_files 'main' 'js' as main_js_files %}
5+
{% get_files 'main' 'js' skip_common_chunks=True as main_js_files %}
66

77
var contentCss = '{{ main_css_files.0.url }}';
88

tests/app/tests/test_webpack.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ def test_code_spliting(self):
149149
def test_templatetags(self):
150150
self.compile_bundles('webpack.config.simple.js')
151151
self.compile_bundles('webpack.config.app2.js')
152+
self.compile_bundles('webpack.config.getFiles.js')
152153
view = TemplateView.as_view(template_name='home.html')
153154
request = self.factory.get('/')
154155
result = view(request)
@@ -169,6 +170,9 @@ def test_templatetags(self):
169170
self.assertIn(
170171
'<img src="/static/my-image.png"/>', result.rendered_content)
171172

173+
self.assertIn('<li>All from getFiles already rendered</li>', result.rendered_content)
174+
175+
request = self.factory.get('/')
172176
view = TemplateView.as_view(template_name='only_files.html')
173177
result = view(request)
174178
self.assertIn((
@@ -180,6 +184,7 @@ def test_templatetags(self):
180184
result.rendered_content)
181185

182186
self.compile_bundles('webpack.config.publicPath.js')
187+
request = self.factory.get('/')
183188
view = TemplateView.as_view(template_name='home.html')
184189
request = self.factory.get('/')
185190
result = view(request)
@@ -527,6 +532,30 @@ def test_emits_warning_on_no_request_in_jinja2engine(self):
527532
_warn_mock.assert_not_called()
528533
_warn_mock.reset_mock()
529534

535+
@patch(
536+
target='webpack_loader.templatetags.webpack_loader.warn',
537+
new=_warn_mock)
538+
def test_get_files_emits_warning_on_no_request(self):
539+
self.compile_bundles('webpack.config.skipCommon.js')
540+
asset_vendor = '"/static/django_webpack_loader_bundles/vendors.js"'
541+
asset_app1 = '"/static/django_webpack_loader_bundles/app1.js"'
542+
asset_app2 = '"/static/django_webpack_loader_bundles/app2.js"'
543+
544+
template = Template(template_string=(
545+
'{% load render_bundle get_files from webpack_loader %}'
546+
'{% render_bundle "app1" %}'
547+
'{% get_files "app2" skip_common_chunks=True as app2_files %}'
548+
'{% for f in app2_files %}'
549+
' <link rel="prefetch" href="{{ f.url }}" />'
550+
'{% endfor %}'),
551+
) # type: Template
552+
output = template.render(context=Context())
553+
self.assertEqual(output.count(asset_app1), 1)
554+
self.assertEqual(output.count(asset_app2), 1)
555+
self.assertEqual(output.count(asset_vendor), 2)
556+
_warn_mock.assert_called_once_with(
557+
message=_WARNING_MESSAGE, category=RuntimeWarning)
558+
530559
def _assert_common_chunks_duplicated_djangoengine(self, template):
531560
"""
532561
Verify that any common chunks between two bundles are duplicated in

tests/assets/js/get_files1.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
h1 {
2+
font-size: 20px;
3+
}

tests/assets/js/get_files2.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
h2 {
2+
font-size: 18px;
3+
}

tests/webpack-stats-getFiles.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"status": "done",
3+
"assets": {
4+
"getFiles.css": {
5+
"name": "getFiles.css",
6+
"path": "/home/fjsj/workspace/django-webpack-loader/tests/assets/django_webpack_loader_bundles/getFiles.css"
7+
},
8+
"getFiles.js": {
9+
"name": "getFiles.js",
10+
"path": "/home/fjsj/workspace/django-webpack-loader/tests/assets/django_webpack_loader_bundles/getFiles.js"
11+
}
12+
},
13+
"chunks": {
14+
"getFiles": [
15+
"getFiles.css",
16+
"getFiles.js"
17+
]
18+
}
19+
}

tests/webpack.config.getFiles.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
var config = require("./webpack.config.simple.js");
2+
var BundleTracker = require('webpack-bundle-tracker');
3+
var MiniCssExtractPlugin = require('mini-css-extract-plugin');
4+
5+
config.entry = {
6+
getFiles: './assets/js/index'
7+
};
8+
9+
config.plugins = [
10+
new MiniCssExtractPlugin(),
11+
new BundleTracker({ path: __dirname, filename: 'webpack-stats-getFiles.json' })
12+
];
13+
14+
module.exports = config;

webpack_loader/templatetags/webpack_loader.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,21 +19,24 @@ def render_bundle(
1919
attrs='', is_preload=False, skip_common_chunks=None):
2020
if skip_common_chunks is None:
2121
skip_common_chunks = utils.get_skip_common_chunks(config)
22-
tags = utils.get_as_tags(
22+
23+
url_to_tag_dict = utils.get_as_url_to_tag_dict(
2324
bundle_name, extension=extension, config=config, suffix=suffix,
2425
attrs=attrs, is_preload=is_preload)
26+
2527
request = context.get('request')
2628
if request is None:
2729
if skip_common_chunks:
2830
warn(message=_WARNING_MESSAGE, category=RuntimeWarning)
29-
return mark_safe('\n'.join(tags.values()))
31+
return mark_safe('\n'.join(url_to_tag_dict.values()))
32+
3033
used_urls = getattr(request, '_webpack_loader_used_urls', None)
3134
if not used_urls:
3235
used_urls = request._webpack_loader_used_urls = set()
3336
if skip_common_chunks:
34-
tags = {url: tag for url, tag in tags.items() if url not in used_urls}
35-
used_urls.update(tags)
36-
return mark_safe('\n'.join(tags.values()))
37+
url_to_tag_dict = {url: tag for url, tag in url_to_tag_dict.items() if url not in used_urls}
38+
used_urls.update(url_to_tag_dict.keys())
39+
return mark_safe('\n'.join(url_to_tag_dict.values()))
3740

3841

3942
@register.simple_tag
@@ -61,16 +64,18 @@ def get_files(
6164
"""
6265
if skip_common_chunks is None:
6366
skip_common_chunks = utils.get_skip_common_chunks(config)
64-
if not skip_common_chunks:
65-
return utils.get_files(bundle_name, extension=extension, config=config)
66-
request = context.get('request')
67+
6768
result = utils.get_files(bundle_name, extension=extension, config=config)
68-
if not skip_common_chunks:
69-
return result
69+
70+
request = context.get('request')
7071
if request is None:
71-
warn(message=_WARNING_MESSAGE, category=RuntimeWarning)
72+
if skip_common_chunks:
73+
warn(message=_WARNING_MESSAGE, category=RuntimeWarning)
7274
return result
75+
7376
used_urls = getattr(request, '_webpack_loader_used_urls', None)
7477
if not used_urls:
75-
used_urls = request._webpack_loader_used_urls = set()
76-
return [x for x in result if x['url'] not in used_urls]
78+
used_urls = set()
79+
if skip_common_chunks:
80+
result = [chunk for chunk in result if chunk['url'] not in used_urls]
81+
return result

webpack_loader/utils.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,15 @@ def get_files(bundle_name, extension=None, config='DEFAULT'):
5757
return list(_get_bundle(loader, bundle_name, extension))
5858

5959

60-
def get_as_tags(bundle_name, extension=None, config='DEFAULT', suffix='', attrs='', is_preload=False):
60+
def get_as_url_to_tag_dict(bundle_name, extension=None, config='DEFAULT', suffix='', attrs='', is_preload=False):
6161
'''
62-
Get a list of formatted <script> & <link> tags for the assets in the
62+
Get a dict of URLs to formatted <script> & <link> tags for the assets in the
6363
named bundle.
6464
6565
:param bundle_name: The name of the bundle
6666
:param extension: (optional) filter by extension, eg. 'js' or 'css'
6767
:param config: (optional) the name of the configuration
68-
:return: a list of formatted tags as strings
68+
:return: a dict of URLs to formatted tags as strings
6969
'''
7070

7171
loader = get_loader(config)
@@ -98,6 +98,19 @@ def get_as_tags(bundle_name, extension=None, config='DEFAULT', suffix='', attrs=
9898
return result
9999

100100

101+
def get_as_tags(bundle_name, extension=None, config='DEFAULT', suffix='', attrs='', is_preload=False):
102+
'''
103+
Get a list of formatted <script> & <link> tags for the assets in the
104+
named bundle.
105+
106+
:param bundle_name: The name of the bundle
107+
:param extension: (optional) filter by extension, eg. 'js' or 'css'
108+
:param config: (optional) the name of the configuration
109+
:return: a list of formatted tags as strings
110+
'''
111+
return get_as_url_to_tag_dict(bundle_name, extension, config, suffix, attrs, is_preload).values()
112+
113+
101114
def get_static(asset_name, config='DEFAULT'):
102115
'''
103116
Equivalent to Django's 'static' look up but for webpack assets.

0 commit comments

Comments
 (0)