-
Notifications
You must be signed in to change notification settings - Fork 338
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New class based loader implementation * Potentially Breaking Changes This commit introduces a new `CACHE` setting which when set to true makes the loader cache the contents of the stats files in memory. This means if set to True, the server will have to be restarted every time the stats file contents change or it'll keep serving old, cached URLs. `CACHE` defaults to `not DEBUG` by default.
- Loading branch information
Showing
10 changed files
with
180 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,4 @@ | ||
__author__ = 'Owais Lone' | ||
__version__ = '0.3.0' | ||
|
||
default_app_config = 'webpack_loader.apps.WebpackLoaderConfig' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import re | ||
|
||
from django.conf import settings | ||
|
||
|
||
__all__ = ('load_config',) | ||
|
||
|
||
DEFAULT_CONFIG = { | ||
'DEFAULT': { | ||
'CACHE': not settings.DEBUG, | ||
'BUNDLE_DIR_NAME': 'webpack_bundles/', | ||
'STATS_FILE': 'webpack-stats.json', | ||
# FIXME: Explore usage of fsnotify | ||
'POLL_INTERVAL': 0.1, | ||
'IGNORE': ['.+\.hot-update.js', '.+\.map'] | ||
} | ||
} | ||
|
||
user_config = getattr(settings, 'WEBPACK_LOADER', DEFAULT_CONFIG) | ||
|
||
user_config = dict( | ||
(name, dict(DEFAULT_CONFIG['DEFAULT'], **cfg)) | ||
for name, cfg in user_config.items() | ||
) | ||
|
||
for entry in user_config.values(): | ||
entry['ignores'] = [re.compile(I) for I in entry['IGNORE']] | ||
|
||
|
||
def load_config(name): | ||
return user_config[name] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
__all__ = ('WebpackError', 'WebpackLoaderBadStatsError') | ||
|
||
|
||
class WebpackError(Exception): | ||
pass | ||
|
||
|
||
class WebpackLoaderBadStatsError(Exception): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import json | ||
import time | ||
|
||
from django.conf import settings | ||
from django.contrib.staticfiles.storage import staticfiles_storage | ||
|
||
from .exceptions import WebpackError, WebpackLoaderBadStatsError | ||
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() | ||
|
||
if settings.DEBUG: | ||
# poll when debugging and block request until bundle is compiled | ||
# TODO: support timeouts | ||
while assets['status'] == 'compiling': | ||
time.sleep(self.config['POLL_INTERVAL']) | ||
assets = self.get_assets() | ||
|
||
if assets.get('status') == 'done': | ||
chunks = assets['chunks'][bundle_name] | ||
return self.filter_chunks(chunks) | ||
|
||
elif assets.get('status') == 'error': | ||
if 'file' not in assets: | ||
assets['file'] = '' | ||
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.") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.