본문 바로가기

68 CSS JS 바로 적용하기- 웹 캐싱 무효화

68.1 css js 파일 적용 후에도 반영이 안된다

filename.js?ver=20221021 이렇게 버전으로 관리하려다가
매번 수정할 때마다 숫자 바꿔주는게 귀찮아서
https://docs.djangoproject.com/en/4.1/ref/에서 찾아보니 ManifestStaticFilesStorage를 발견했다.

CSS, JS 등 정적파일 이름의 해시값으로 관리하면
내용이 변경되면 브라우저에서 파일을 로드하므로 바로 적용된 화면을 볼 수 있으며,
내용이 변경될 경우만 로드하기때문에 트래픽을 절감할 수 있다.

개발자가 작업하면서 파일을 반영하고 캐시비우기+새로고침이 아닌 F5만 하면 된다는점도 좋다.

브라우저 캐싱
css , js 파일 등 정적파일들은 웹사이트 접속시에 사용자 PC의 특정 폴더에 저장해놓고 사용자가 재 방문시 웹사이트에서 파일을 다운로드하는 것이 아닌 사용자 PC에 저장되어 있는 파일을 읽음으로써 빠르게 불러오고 서버에는 트래픽 낭비를 방지할 수 있는 효과

68.2 ManifestStaticFilesStorage ValueError Missing staticfiles manifest entry for XXXX

DJango Documentation에서는
ManifestStaticFilesStorage 를 setting.py에 적용해주면 된다고 하였으나 안된다.

#https://docs.djangoproject.com/en/4.1/ref/contrib/staticfiles/#manifeststaticfilesstorage
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

ValueError: Missing staticfiles manifest entry for XXXX 에러가 발생하며 서버가 종료된다. ㅠㅠ

https://docs.djangoproject.com/en/4.1/ref/contrib/staticfiles/#manifeststaticfilesstorage

68.3 hashed_name 상속 - base.py storage.py

ManifestStaticFilesStorage 에러해결을 위해 이것저것 해보다가
github에서 해결한 소스를 발견했다.

storage.py의 hashed_name를 오버라이딩하여 해당 에러 부분을 제거한 소스였다.


소스출처: https://github.com/InhaBas/Inhabas.com/blob/dev/Back_end/IBAS/storage.py



setting파일에 myapp.common.storage.StaticFilesMd5HashingStorage 추가

/config/settings/base.py

#https://docs.djangoproject.com/en/4.1/ref/contrib/staticfiles/#manifeststaticfilesstorage
# STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'

#https://github.com/InhaBas/Inhabas.com/blob/dev/Back_end/IBAS/storage.py
STATICFILES_STORAGE = 'myapp.common.storage.StaticFilesMd5HashingStorage'


/myapp/common/storage.py 소스

from django.contrib.staticfiles.storage import ManifestStaticFilesStorage
from urllib.parse import unquote, urlsplit, urlunsplit
import os


class StaticFilesMd5HashingStorage(ManifestStaticFilesStorage):
    manifest_strict = False

    def hashed_name(self, name, content=None, filename=None):
        # `filename` is the name of file to hash if `content` isn't given.
        # `name` is the base name to construct the new hashed filename from.
        parsed_name = urlsplit(unquote(name))
        clean_name = parsed_name.path.strip()
        filename = (filename and urlsplit(unquote(filename)).path.strip()) or clean_name
        opened = content is None
        if opened:
            if not self.exists(filename):
                # raise ValueError("The file '%s' could not be found with %r." % (filename, self))
                return name
            try:
                content = self.open(filename)
            except OSError:
                # Handle directory paths and fragments
                return name
        try:
            file_hash = self.file_hash(clean_name, content)
        finally:
            if opened:
                content.close()
        path, filename = os.path.split(clean_name)
        root, ext = os.path.splitext(filename)
        file_hash = ('.%s' % file_hash) if file_hash else ''
        hashed_name = os.path.join(path, "%s%s%s" %
                                   (root, file_hash, ext))
        unparsed_name = list(parsed_name)
        unparsed_name[2] = hashed_name
        # Special casing for a @font-face hack, like url(myfont.eot?#iefix")
        # http://www.fontspring.com/blog/the-new-bulletproof-font-face-syntax
        if '?#' in name and not unparsed_name[3]:
            unparsed_name[2] += '?'
        return urlunsplit(unparsed_name)

68.4 python manage.py collectstatic

static root의 파일을 모두 삭제하고
쉘에서 python manage.py collectstatic 명령을 치면
bootstrap.bundle.3ddb03a6eb14.js 형식의 파일들이 생성되는 것을 볼수 있다.

python manage.py  collectstatic

68.5 적용 확인하기

크롬 개발자모드에서 소스를 여러보면 정적파일명 들이 변경되고 적용되어 있음을 확인 할 수 있다.

테스트로 ncp_mail.js 파일을 수정하여 배포/재기동 후 확인 시 파일명이 변한것을 확인 할 수 있다.

이제 정적 파일 수정 사항이 바로바로 반영 되겠지..

현재글 : 68 CSS JS 바로 적용하기- 웹 캐싱 무효화
Comments
Login:

Copyright © PythonBlog 2021 - 2022 All rights reserved
Mail : PYTHONBLOG