diff --git a/webpack_loader/loaders.py b/webpack_loader/loaders.py
index f6855739..7a81857d 100644
--- a/webpack_loader/loaders.py
+++ b/webpack_loader/loaders.py
@@ -14,7 +14,7 @@
)
-class WebpackLoader(object):
+class WebpackLoader:
_assets = {}
def __init__(self, name, config):
@@ -82,7 +82,7 @@ def map_chunk_files_to_url(self, chunks):
def get_chunk_url(self, chunk_file):
public_path = chunk_file.get("publicPath")
- if public_path:
+ if public_path and public_path != "auto":
return public_path
# Use os.path.normpath for Windows paths
@@ -91,26 +91,48 @@ def get_chunk_url(self, chunk_file):
)
return staticfiles_storage.url(relpath)
- def get_bundle(self, bundle_name):
+ def wait_for_assets(self):
assets = self.get_assets()
# poll when debugging and block request until bundle is compiled
# or the build times out
if settings.DEBUG:
timeout = self.config["TIMEOUT"] or 0
- timed_out = False
start = time.time()
- while assets["status"] == "compile" and not timed_out:
+ while assets["status"] == "compile":
time.sleep(self.config["POLL_INTERVAL"])
if timeout and (time.time() - timeout > start):
- timed_out = True
+ raise WebpackLoaderTimeoutError(
+ "Timed Out. Webpack took more than {0} "
+ "seconds to compile.".format(self.config["TIMEOUT"] or 0)
+ )
+
assets = self.get_assets()
- if timed_out:
- raise WebpackLoaderTimeoutError(
- "Timed Out. Bundle `{0}` took more than {1} seconds "
- "to compile.".format(bundle_name, timeout)
- )
+ return assets
+
+ def _process_assets_error(self, assets):
+ if assets.get("status") == "error":
+ if "file" not in assets:
+ assets["file"] = ""
+ if "error" not in assets:
+ assets["error"] = "Unknown Error"
+ if "message" not in assets:
+ assets["message"] = ""
+ error = """
+ {error} in {file}
+ {message}
+ """.format(**assets)
+ raise WebpackError(error)
+
+ raise WebpackLoaderBadStatsError(
+ "The stats file does not contain valid data. Make sure "
+ "webpack-bundle-tracker plugin is enabled and try to run "
+ "webpack again."
+ )
+
+ def get_bundle(self, bundle_name):
+ assets = self.wait_for_assets()
if assets.get("status") == "done":
chunks = assets["chunks"].get(bundle_name, None)
@@ -130,24 +152,17 @@ def get_bundle(self, bundle_name):
return self.map_chunk_files_to_url(filtered_chunks)
- elif assets.get("status") == "error":
- if "file" not in assets:
- assets["file"] = ""
- if "error" not in assets:
- assets["error"] = "Unknown Error"
- if "message" not in assets:
- assets["message"] = ""
- error = """
- {error} in {file}
- {message}
- """.format(**assets)
- raise WebpackError(error)
+ self._process_assets_error(assets)
- raise WebpackLoaderBadStatsError(
- "The stats file does not contain valid data. Make sure "
- "webpack-bundle-tracker plugin is enabled and try to run "
- "webpack again."
- )
+ def get_asset_url(self, asset_name):
+ assets = self.wait_for_assets()
+ try:
+ asset_file = assets["assets"][asset_name]
+ except KeyError:
+ raise WebpackBundleLookupError(
+ "Cannot resolve asset {0}.".format(asset_name)
+ )
+ return self.get_chunk_url(asset_file)
class FakeWebpackLoader(WebpackLoader):
diff --git a/webpack_loader/utils.py b/webpack_loader/utils.py
index ca844fac..228aa2e4 100644
--- a/webpack_loader/utils.py
+++ b/webpack_loader/utils.py
@@ -6,24 +6,24 @@
def import_string(dotted_path):
- '''
+ """
This is a rough copy of django's import_string, which wasn't introduced until Django 1.7
Once this package's support for Django 1.6 has been removed, this can be safely replaced with
`from django.utils.module_loading import import_string`
- '''
+ """
try:
- module_path, class_name = dotted_path.rsplit('.', 1)
+ module_path, class_name = dotted_path.rsplit(".", 1)
module = import_module(module_path)
return getattr(module, class_name)
except (ValueError, AttributeError, ImportError):
- raise ImportError('%s doesn\'t look like a valid module path' % dotted_path)
+ raise ImportError("%s doesn't look like a valid module path" % dotted_path)
def get_loader(config_name):
if config_name not in _loaders:
config = load_config(config_name)
- loader_class = import_string(config['LOADER_CLASS'])
+ loader_class = import_string(config["LOADER_CLASS"])
_loaders[config_name] = loader_class(config_name, config)
return _loaders[config_name]
@@ -33,13 +33,13 @@ def get_skip_common_chunks(config_name):
# The global default is currently False, whenever that is changed, change
# this fallback value as well which is present to provide backwards
# compatibility.
- return loader.config.get('SKIP_COMMON_CHUNKS', False)
+ return loader.config.get("SKIP_COMMON_CHUNKS", False)
def _filter_by_extension(bundle, extension):
- '''Return only files with the given extension'''
+ """Return only files with the given extension"""
for chunk in bundle:
- if chunk['name'].endswith('.{0}'.format(extension)):
+ if chunk["name"].endswith(".{0}".format(extension)):
yield chunk
@@ -50,14 +50,16 @@ def _get_bundle(loader, bundle_name, extension):
return bundle
-def get_files(bundle_name, extension=None, config='DEFAULT'):
- '''Returns list of chunks from named bundle'''
+def get_files(bundle_name, extension=None, config="DEFAULT"):
+ """Returns list of chunks from named bundle"""
loader = get_loader(config)
return list(_get_bundle(loader, bundle_name, extension))
-def get_as_tags(bundle_name, extension=None, config='DEFAULT', suffix='', attrs='', is_preload=False):
- '''
+def get_as_tags(
+ bundle_name, extension=None, config="DEFAULT", suffix="", attrs="", is_preload=False
+):
+ """
Get a list of formatted '
- ).format(
- ''.join([chunk['url'], suffix]),
+ tags.append(
+ ('').format(
+ "".join([chunk["url"], suffix]),
+ attrs,
+ loader.get_integrity_attr(chunk),
+ )
+ )
+ elif chunk["name"].endswith((".css", ".css.gz")):
+ tags.append(
+ ('').format(
+ "".join([chunk["url"], suffix]),
attrs,
+ '"stylesheet"' if not is_preload else '"preload" as="style"',
loader.get_integrity_attr(chunk),
- ))
- elif chunk['name'].endswith(('.css', '.css.gz')):
- tags.append((
- ''
- ).format(
- ''.join([chunk['url'], suffix]),
- attrs,
- '"stylesheet"' if not is_preload else '"preload" as="style"',
- loader.get_integrity_attr(chunk),
- ))
+ )
+ )
return tags
-def get_static(asset_name, config='DEFAULT'):
- '''
+def get_static(asset_name, config="DEFAULT"):
+ """
Equivalent to Django's 'static' look up but for webpack assets.
:param asset_name: the name of the asset
:param config: (optional) the name of the configuration
:return: path to webpack asset as a string
- '''
- return "{0}{1}".format(
- get_loader(config).get_assets().get(
- 'publicPath', getattr(settings, 'STATIC_URL')
- ),
- asset_name
- )
+ """
+ loader = get_loader(config)
+ return loader.get_asset_url(asset_name)