작성
·
110
답변 2
1
해당 코드를 살펴보니, component_js_dependencies 호출 시에 수집된 컴포넌트 클래스 목록의 순서가, 해당 템플릿 태그가 호출이 될 때마다 변경이 되는 django-components 라이브러리의 버그(?)가 있네요.
컴포넌트 클래스 목록을 사전으로 관리되고 있고, 이를 집합으로 가공하는 과정에서 클래스 목록 순서가 그때그때 달라지네요. 그래서 compress 명령 때와 서비스 때의 컴포넌트 클래스 목록은 같지만 순서가 달라서 생성되는 HTML 코드가 다르니까 해싱 key도 달라지는 문제로 보여집니다.
get_components_from_registry 함수 내에서 unique_component_classes 집합 생성 후에, 클래스 이름으로 정렬을 한 번 해주면 이 문제가 해결될 것으로 보여집니다. 한 번 이슈를 제기해봐야겠네요.
--
일단 아래와 같이 몽키패치를 해보실 수 있으시겠습니다.
# core/patch_django_components.py
from django_components.component_registry import ComponentRegistry
from django_components.templatetags import component_tags
def new_get_components_from_registry(registry: ComponentRegistry):
unique_component_classes = set(registry.all().values())
# added
unique_component_classes = sorted(
unique_component_classes,
key=lambda cls: cls.__name__,
)
components = []
for component_class in unique_component_classes:
components.append(component_class(component_class.__name__))
return components
setattr(
component_tags, "get_components_from_registry", new_get_components_from_registry
)
위 코드 저장하시고, settings 등에서 임포트해주시면, get_components_from_registry 함수를 바꿀 수 있습니다.
살펴보시고 댓글 남겨주세요. :-)
1
안녕하세요.
component_js_dependencies 템플릿 태그에서는 각 Component 의 render_js_dependencies 메서드를 호출하여 "<script src=js경로></script>\n<script src=js경로></script>" 문자열을 생성합니다.
위 소스코드를 보시면, render_js_dependencies 메서드 내에서 <script>{self.js}</script> 코드와 self.media.render_js() 코드를 통해 script 태그를 조합하여, script 태그 문자열을 조합하는 데요. 기본 구현에서는 script 태그에 src 속성 외에는 추가 속성은 지원하고 있지 않습니다.
이 script 태그에 async와 defer 속성을 추가하실려면, 각 Component 클래스의 render_js_dependencies 메서드를 재정의하신 후에, 아래처럼 문자열 변경으로 원하시는 속성을 추가해주실 수 있습니다.
@component.register("예시")
class ExampleComponent(component.Component):
# 생략
def render_js_dependencies(self) -> SafeString:
html = super().render_js_dependencies()
html = html.replace("<script", "<script defer")
return mark_safe(html)
살펴보시고 댓글 남겨주세요.
화이팅입니다. :-)