Fixed #32383 -- Added source map support to ManifestStaticFilesStorage.

This commit is contained in:
Adam Johnson 2021-01-26 23:10:00 +00:00 committed by Mariusz Felisiak
parent 9ee693bd6c
commit e32722d160
7 changed files with 48 additions and 9 deletions

View File

@ -49,6 +49,9 @@ class HashedFilesMixin:
r"""(url\(['"]{0,1}\s*(.*?)["']{0,1}\))""",
(r"""(@import\s*["']\s*(.*?)["'])""", """@import url("%s")"""),
)),
('*.js', (
(r'(?m)^(//# (?-i:sourceMappingURL)=(.*))$', '//# sourceMappingURL=%s'),
)),
)
keep_intermediate_files = True

View File

@ -291,24 +291,30 @@ The storage backend automatically replaces the paths found in the saved
files matching other saved files with the path of the cached copy (using
the :meth:`~django.contrib.staticfiles.storage.StaticFilesStorage.post_process`
method). The regular expressions used to find those paths
(``django.contrib.staticfiles.storage.HashedFilesMixin.patterns``)
by default covers the `@import`_ rule and `url()`_ statement of `Cascading
Style Sheets`_. For example, the ``'css/styles.css'`` file with the
content
(``django.contrib.staticfiles.storage.HashedFilesMixin.patterns``) cover:
* The `@import`_ rule and `url()`_ statement of `Cascading Style Sheets`_.
* The `source map`_ comment in JavaScript.
For example, the ``'css/styles.css'`` file with this content:
.. code-block:: css
@import url("../admin/css/base.css");
would be replaced by calling the :meth:`~django.core.files.storage.Storage.url`
method of the ``ManifestStaticFilesStorage`` storage backend, ultimately
saving a ``'css/styles.55e7cbb9ba48.css'`` file with the following
content:
...would be replaced by calling the
:meth:`~django.core.files.storage.Storage.url` method of the
``ManifestStaticFilesStorage`` storage backend, ultimately saving a
``'css/styles.55e7cbb9ba48.css'`` file with the following content:
.. code-block:: css
@import url("../admin/css/base.27e20196a850.css");
.. versionchanged:: 4.0
Support for finding paths in the source map comments was added.
.. attribute:: storage.ManifestStaticFilesStorage.max_post_process_passes
Since static files might reference other static files that need to have their
@ -361,6 +367,7 @@ hashing algorithm.
.. _`@import`: https://www.w3.org/TR/CSS2/cascade.html#at-import
.. _`url()`: https://www.w3.org/TR/CSS2/syndata.html#uri
.. _`Cascading Style Sheets`: https://www.w3.org/Style/CSS/
.. _`source map`: https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map
``ManifestFilesMixin``
----------------------

View File

@ -136,7 +136,9 @@ Minor features
:mod:`django.contrib.staticfiles`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* ...
* :class:`~django.contrib.staticfiles.storage.ManifestStaticFilesStorage` now
replaces paths to JavaScript source map references with their hashed
counterparts.
:mod:`django.contrib.syndication`
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -0,0 +1 @@
//# sourceMappingURL=source_map.js.map

View File

@ -0,0 +1 @@
//# sOuRcEMaPpInGURL=source_map.js.map

View File

@ -216,6 +216,30 @@ class TestHashedFiles:
self.assertIn(b"other.d41d8cd98f00.css", content)
self.assertPostCondition()
def test_js_source_map(self):
relpath = self.hashed_file_path('cached/source_map.js')
self.assertEqual(relpath, 'cached/source_map.9371cbb02a26.js')
with storage.staticfiles_storage.open(relpath) as relfile:
content = relfile.read()
self.assertNotIn(b'//# sourceMappingURL=source_map.js.map', content)
self.assertIn(
b'//# sourceMappingURL=source_map.js.99914b932bd3.map',
content,
)
self.assertPostCondition()
def test_js_source_map_sensitive(self):
relpath = self.hashed_file_path('cached/source_map_sensitive.js')
self.assertEqual(relpath, 'cached/source_map_sensitive.5da96fdd3cb3.js')
with storage.staticfiles_storage.open(relpath) as relfile:
content = relfile.read()
self.assertIn(b'//# sOuRcEMaPpInGURL=source_map.js.map', content)
self.assertNotIn(
b'//# sourceMappingURL=source_map.js.99914b932bd3.map',
content,
)
self.assertPostCondition()
@override_settings(
STATICFILES_DIRS=[os.path.join(TEST_ROOT, 'project', 'faulty')],
STATICFILES_FINDERS=['django.contrib.staticfiles.finders.FileSystemFinder'],