-
Notifications
You must be signed in to change notification settings - Fork 336
/
loader.py
99 lines (83 loc) · 3.24 KB
/
loader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import json
import time
from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from .exceptions import (
WebpackError,
WebpackLoaderBadStatsError,
WebpackLoaderTimeoutError,
WebpackBundleLookupError
)
from .config import load_config
class WebpackLoader(object):
_assets = {}
def __init__(self, name='DEFAULT'):
self.name = name
self.config = load_config(self.name)
def _load_assets(self):
try:
with open(self.config['STATS_FILE']) as f:
return json.load(f)
except IOError:
raise IOError(
'Error reading {0}. Are you sure webpack has generated '
'the file and the path is correct?'.format(
self.config['STATS_FILE']))
def get_assets(self):
if self.config['CACHE']:
if self.name not in self._assets:
self._assets[self.name] = self._load_assets()
return self._assets[self.name]
return self._load_assets()
def filter_chunks(self, chunks):
for chunk in chunks:
ignore = any(regex.match(chunk['name'])
for regex in self.config['ignores'])
if not ignore:
chunk['url'] = self.get_chunk_url(chunk)
yield chunk
def get_chunk_url(self, chunk):
public_path = chunk.get('publicPath')
if public_path:
return public_path
relpath = '{0}{1}'.format(
self.config['BUNDLE_DIR_NAME'], chunk['name']
)
return staticfiles_storage.url(relpath)
def get_bundle(self, bundle_name):
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'] == 'compiling' and not timed_out:
time.sleep(self.config['POLL_INTERVAL'])
if timeout and (time.time() - timeout > start):
timed_out = True
assets = self.get_assets()
if timed_out:
raise WebpackLoaderTimeoutError(
"Timed Out. Bundle `{0}` took more than {1} seconds "
"to compile.".format(bundle_name, timeout)
)
if assets.get('status') == 'done':
chunks = assets['chunks'].get(bundle_name, None)
if chunks is None:
raise WebpackBundleLookupError('Cannot resolve bundle {0}.'.format(bundle_name))
return self.filter_chunks(chunks)
elif assets.get('status') == 'error':
if 'file' not in assets:
assets['file'] = ''
if 'error' not in assets:
assets['error'] = 'Unknown Error'
error = u"""
{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.")