Skip to content

Commit

Permalink
added requirements to setup.py and updated asset_loader.py: dynamic d…
Browse files Browse the repository at this point in the history
…ev mode + fix for static urls
  • Loading branch information
DaanDL committed Mar 5, 2024
1 parent ff6d7a9 commit cce7672
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 13 deletions.
55 changes: 42 additions & 13 deletions django_vite/core/asset_loader.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import requests
from requests.adapters import HTTPAdapter
import json
import urllib3
from pathlib import Path
from typing import Dict, List, Callable, NamedTuple, Optional, Union
from urllib.parse import urljoin
Expand Down Expand Up @@ -51,6 +54,32 @@ class DjangoViteConfig(NamedTuple):
react_refresh_url: str = "@react-refresh"


def evaluate_dev_mode(config: DjangoViteConfig) -> bool:
"""
====
When running in "dev mode", check that an actual vite webserver is running
If not: fallback to serving the actual bundled version read from the manifest.json
====
When "dev mode" was false to begin with, this means that we're running in prod and should never
check for a running vite webserver instance to begin with
"""
if config.dev_mode:
print("Evaluating dev mode..")
# Hacky way to check if the vite webserver is serving something
vite_webserver_url = f"http://{config.dev_server_host}:{config.dev_server_port}/"
try:
session = requests.Session()
session.mount(vite_webserver_url, HTTPAdapter(max_retries=0))
response = session.get(vite_webserver_url)
return response.status_code == 404
except urllib3.exceptions.MaxRetryError:
return False
except requests.exceptions.ConnectionError:
return False
else:
return False


class ManifestEntry(NamedTuple):
"""
Represent an entry for a file inside the "manifest.json".
Expand Down Expand Up @@ -80,7 +109,6 @@ def __init__(
self._config = config
self.app_name = app_name

self.dev_mode = config.dev_mode
self.manifest_path = self._clean_manifest_path()
self.legacy_polyfills_motif = config.legacy_polyfills_motif

Expand All @@ -90,7 +118,7 @@ def __init__(
# Don't crash if there is an error while parsing manifest.json.
# Running DjangoViteAssetLoader.instance().checks() on startup will log any
# errors.
if not self.dev_mode:
if not evaluate_dev_mode(config):
try:
self._entries, self.legacy_polyfills_entry = self._parse_manifest()
except DjangoViteManifestError:
Expand Down Expand Up @@ -120,7 +148,7 @@ def _clean_manifest_path(self) -> Path:
def check(self) -> List[Warning]:
"""Check that manifest files are valid when dev_mode=False."""
try:
if not self.dev_mode:
if not evaluate_dev_mode(self._config):
self._parse_manifest()
return []
except DjangoViteManifestError as exception:
Expand Down Expand Up @@ -156,7 +184,7 @@ def _parse_manifest(self) -> ParsedManifestOutput:
DjangoViteManifestError: if cannot load the file or JSON in file is
malformed.
"""
if self.dev_mode:
if evaluate_dev_mode(self._config):
return self.ParsedManifestOutput()

entries: Dict[str, ManifestEntry] = {}
Expand Down Expand Up @@ -218,7 +246,6 @@ def __init__(
self._config = config
self.app_name = app_name

self.dev_mode = config.dev_mode
self.dev_server_protocol = config.dev_server_protocol
self.dev_server_host = config.dev_server_host
self.dev_server_port = config.dev_server_port
Expand All @@ -241,7 +268,9 @@ def _get_dev_server_url(
Returns:
str -- Full URL to the asset.
"""
static_url_base = urljoin(settings.STATIC_URL, self.static_url_prefix)
# Override from default library, we don't want the static_url_base to be used as in our case
# this is an actual url and not a relative path
static_url_base = urljoin('', self.static_url_prefix)
if not static_url_base.endswith("/"):
static_url_base += "/"

Expand Down Expand Up @@ -302,7 +331,7 @@ def generate_vite_asset(
this asset in your page.
"""

if self.dev_mode:
if evaluate_dev_mode(self._config):
url = self._get_dev_server_url(path)
return TagGenerator.script(
url,
Expand Down Expand Up @@ -367,7 +396,7 @@ def preload_vite_asset(
str -- all <link> tags to preload
this asset.
"""
if self.dev_mode:
if evaluate_dev_mode(self._config):
return ""

tags: List[Tag] = []
Expand Down Expand Up @@ -480,7 +509,7 @@ def generate_vite_asset_url(self, path: str) -> str:
str -- The URL of this asset.
"""

if self.dev_mode:
if evaluate_dev_mode(self._config):
return self._get_dev_server_url(path)

manifest_entry = self.manifest.get(path)
Expand Down Expand Up @@ -509,7 +538,7 @@ def generate_vite_legacy_polyfills(
str -- The script tag to the polyfills.
"""

if self.dev_mode:
if evaluate_dev_mode(self._config):
return ""

polyfills_manifest_entry = self.manifest.legacy_polyfills_entry
Expand Down Expand Up @@ -554,7 +583,7 @@ def generate_vite_legacy_asset(
str -- The script tag of this legacy asset .
"""

if self.dev_mode:
if evaluate_dev_mode(self._config):
return ""

manifest_entry = self.manifest.get(path)
Expand All @@ -580,7 +609,7 @@ def generate_vite_ws_client(self, **kwargs: Dict[str, str]) -> str:
script tags.
"""

if not self.dev_mode:
if not evaluate_dev_mode(self._config):
return ""

url = self._get_dev_server_url(self.ws_client_url)
Expand All @@ -605,7 +634,7 @@ def generate_vite_react_refresh_url(self, **kwargs: Dict[str, str]) -> str:
config_key {str} -- Key of the configuration to use.
"""

if not self.dev_mode:
if not evaluate_dev_mode(self._config):
return ""

url = self._get_dev_server_url(self.react_refresh_url)
Expand Down
2 changes: 2 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
],
install_requires=[
"Django>=3.2",
"requests>=2.31.0",
"urllib3>=1.26.18",
],
classifiers=[
"License :: OSI Approved :: Apache Software License",
Expand Down

0 comments on commit cce7672

Please sign in to comment.