Django-compressor: μ˜€ν”„λΌμΈ 압좕을 μ‚¬μš©ν•˜λ„λ‘ μ„€μ •ν–ˆμ§€λ§Œ μ˜€ν”„λΌμΈ λ§€λ‹ˆνŽ˜μŠ€νŠΈμ— ν‚€κ°€ μ—†μŠ΅λ‹ˆλ‹€.

에 λ§Œλ“  2011λ…„ 12μ›” 01일  Β·  17μ½”λ©˜νŠΈ  Β·  좜처: django-compressor/django-compressor

이 λ¬Έμ œκ°€ 무엇인지 ν™•μ‹€ν•˜μ§€ μ•Šμ§€λ§Œ μ˜€ν”„λΌμΈ 생성을 μ‚¬μš©ν•˜κ³  있으며 이 였λ₯˜λŠ” μ••μΆ• 관리 λͺ…령을 μ‚¬μš©ν•˜κ³  μ›Ήμ‚¬μ΄νŠΈμ— μ•‘μ„ΈμŠ€ν•œ 후에 λ°œμƒν•©λ‹ˆλ‹€. ν•΄λ‹Ή CSS 파일 각각에 κ³ μœ ν•œ ν‚€κ°€ μžˆμ–΄μ•Ό ν•©λ‹ˆκΉŒ?

λ‚΄ μ„€μ •:
COMPRESS_URL = STATIC_URL
COMPRESS_ROOT = 정적_루트
COMPRESS_OFFLINE = μ°Έ
COMPRESS_OFFLINE_MANIFEST = "manifest.json" # CACHE 디렉토리에 생성
COMPRESS_CSS_FILTERS = ['compressor.filters.css_default.CssAbsoluteFilter','compressor.filters.cssmin.CSSMinFilter']
COMPRESS_YUI_BINARY = os.path.join(PROJECT_ROOT, 'bin/yui.sh')
COMPRESS_JS_FILTERS = ['compressor.filters.closure.ClosureCompilerFilter']
COMPRESS_CLOSURE_COMPILER_BINARY = os.path.join(PROJECT_ROOT, 'bin/closure.sh')
COMPRESS_CLOSURE_COMPILER_ARGUMENTS = "--language_in=ECMASCRIPT5"

COMPRESS_STORAGE = 'compressor.storage.GzipCompressorFileStorage' # WTFμ—μ„œ μž‘λ™ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

μ˜€ν”„λΌμΈ 압좕을 μ‚¬μš©ν•˜λ„λ‘ μ„€μ •ν–ˆμ§€λ§Œ μ˜€ν”„λΌμΈ λ§€λ‹ˆνŽ˜μŠ€νŠΈμ—μ„œ "b68ba4d2116295c56138e439f1b03a03" ν‚€κ°€ λˆ„λ½λ˜μ—ˆμŠ΅λ‹ˆλ‹€. "python manage.py compress"λ₯Ό μ‹€ν–‰ν•΄μ•Ό ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.

μš”μ²­ 방법: GET
μš”μ²­ URL: http://127.0.0.1 :8000/
μž₯κ³  버전: 1.3.1
μ˜ˆμ™Έ μœ ν˜•: OfflineGenerationError
μ˜ˆμ™Έ κ°’:
μ˜€ν”„λΌμΈ 압좕을 μ‚¬μš©ν•˜λ„λ‘ μ„€μ •ν–ˆμ§€λ§Œ μ˜€ν”„λΌμΈ λ§€λ‹ˆνŽ˜μŠ€νŠΈμ—μ„œ "b68ba4d2116295c56138e439f1b03a03" ν‚€κ°€ λˆ„λ½λ˜μ—ˆμŠ΅λ‹ˆλ‹€. "python manage.py compress"λ₯Ό μ‹€ν–‰ν•΄μ•Ό ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
μ˜ˆμ™Έ μœ„μΉ˜: /srv/www/project/lib/python2.6/site-packages/compressor/templatetags/compress.py의 render_offline, 56ν–‰

Variable    Value
forced  
False
self    
<compressor.templatetags.compress.CompressorNode object at 0x966764c>
compressor  
<compressor.js.JsCompressor object at 0x966732c>
key 
'b68ba4d2116295c56138e439f1b03a03'
offline_manifest    
{u'32e9172ad82f3b6d238cc7423a7f10c7': u'<link rel="stylesheet" href="/static/CACHE/css/a50381ce7ba9.css" type="text/css" media="screen" /><link rel="stylesheet" href="/static/CACHE/css/62afac347423.css" type="text/css" /><link rel="stylesheet" href="/static/CACHE/css/f336d54a5423.css" type="text/css" media="screen" /><link rel="stylesheet" href="/static/CACHE/css/5cf783d07673.css" type="text/css" />',
 u'b1bd8f68f96dfa53380b10881f8eb691': u'<script type="text/javascript" src="/static/CACHE/js/19522c6ee302.js"></script>',
 u'c6d6d2948d18188277e7a987c71e2bc3': u'<script type="text/javascript" src="/static/CACHE/js/90bda37980a5.js"></script>',
 u'dbe0b22545cd64193d8a875c3226b1ea': u'<script type="text/javascript" src="/static/CACHE/js/71056921eb77.js"></script>'}

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

같은 일이 μΌμ–΄λ‚˜μ‹­μ‹œμ˜€. 압좕에 인라인 μ½”λ“œκ°€ μ—†μœΌλ©° λˆ„λ½λœ κ²ƒμœΌλ‘œ λ³΄κ³ ν•˜λŠ” ν‚€λŠ” μ‹€μ œλ‘œ manifest.json에 μžˆμŠ΅λ‹ˆλ‹€.
λ„λŒ€μ²΄ 무슨 일이 μΌμ–΄λ‚˜κ³  μžˆλŠ”μ§€ 정말 λͺ¨λ₯΄κ² μ–΄, λ‹€λ₯Έ μ‚¬λžŒμ΄ 아직도 이것을 가지고 μžˆλ‹ˆ? 이것에 λŒ€ν•œ λ‹€λ₯Έ λͺ¨λ“  λŒ“κΈ€μ€ 1λ…„ μ „μ˜ κ²ƒμž…λ‹ˆλ‹€.

λͺ¨λ“  17 λŒ“κΈ€

μ–΄λ–€ λ²„μ „μ˜ django_compressorλ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆκΉŒ?

PyPI에 μžˆλŠ” λͺ¨λ“  것. μ΅œμ‹  개발자 λ²„μ „μœΌλ‘œ μ—…κ·Έλ ˆμ΄λ“œν•˜λ €κ³  ν•©λ‹ˆλ‹€. 감사 ν•΄μš”

인라인 슀크립트λ₯Ό ν¬ν•¨λœ 파일과 ν˜Όν•©ν•˜μ—¬ λ™μΌν•œ λ¬Έμ œκ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

이것은 λ‚΄ ν…œν”Œλ¦Ώ μ½”λ“œμ˜€μŠ΅λ‹ˆλ‹€.

{% compress js %}
    <script type="text/javascript">
    xhr_cidades = '{% url cidades_consulta %}';
    xhr_imoveis = '{% url imoveis_consulta %}';
    xhr_empresas = '{% url empresas_consulta %}';
    xhr_empreend = '{% url empreendimentos_consulta %}';
    </script>

    <script type="text/javascript" src="{{ STATIC_URL }}jquery-1.6.1.min.js"></script>
    <script type="text/javascript" src="{{ STATIC_URL }}jquery-ui/jquery-ui-1.8.13.custom.min.js"></script>
    <script type="text/javascript" src="{{ STATIC_URL }}jquery-ui/jquery-ui-datepicker-pt-BR.min.js"></script>
    <script type="text/javascript" src="{{ STATIC_URL }}jquery-ui/jquery-ui-combobox.min.js"></script>
    <script type="text/javascript" src="{{ STATIC_URL }}jquery-meiomask-1.1.3.min.js"></script>
    <script type="text/javascript" src="{{ STATIC_URL }}jquery-scrollto-1.4.2.min.js"></script>
    <script type="text/javascript" src="{{ STATIC_URL }}jquery-dotimeout-1.0.min.js"></script>
    <script type="text/javascript" src="{{ STATIC_URL }}base.js"></script>
{% endcompress %}

그리고 이것은 Django μ••μΆ•κΈ°κ°€ λ§€λ‹ˆνŽ˜μŠ€νŠΈ ν‚€λ₯Ό μƒμ„±ν•˜λŠ” 데 μ‚¬μš©ν•˜λŠ” λ°μ΄ν„°μ˜€μŠ΅λ‹ˆλ‹€.

['\n    <script type="text/javascript">\n        xhr_cidades = \'', '<django.template.defaulttags.URLNode object at 0x23cf1d0>',
 "';\n        xhr_imoveis = '", '<django.template.defaulttags.URLNode object at 0x23cf750>', "';\n        xhr_empresas = '",
 '<django.template.defaulttags.URLNode object at 0x23cf210>', "';\n        xhr_empreend = '",
 '<django.template.defaulttags.URLNode object at 0x23cf2d0>', '\';\n    </script>\n\n    <script type="text/javascript" src="',
 '<Variable Node: STATIC_URL>', 'jquery-1.6.1.min.js"></script>\n    <script type="text/javascript" src="', '<Variable Node:
 STATIC_URL>', 'jquery-ui/jquery-ui-1.8.13.custom.min.js"></script>\n    <script type="text/javascript" src="', '<Variable
 Node: STATIC_URL>', 'jquery-ui/jquery-ui-datepicker-pt-BR.min.js"></script>\n    <script type="text/javascript" src="',
 '<Variable Node: STATIC_URL>', 'jquery-ui/jquery-ui-combobox.min.js"></script>\n    <script type="text/javascript" src="',
 '<Variable Node: STATIC_URL>', 'jquery-meiomask-1.1.3.min.js"></script>\n    <script type="text/javascript" src="',
 '<Variable Node: STATIC_URL>', 'jquery-scrollto-1.4.2.min.js"></script>\n    <script type="text/javascript" src="', '<Variable
 Node: STATIC_URL>', 'base.js"></script>\n']

ν‚€λŠ” {% compress %} 블둝 λ‚΄ λ…Έλ“œ λͺ©λ‘μ˜ λ¬Έμžμ—΄ ν‘œν˜„ λ‹€μ΄μ œμŠ€νŠΈμž…λ‹ˆλ‹€. 블둝이 ꡬ문 뢄석될 λ•Œλ§ˆλ‹€ ν•΄λ‹Ή 데이터가 달라지면(μœ„μ˜ URLNodeμ—μ„œ 0x23cf750 μ£Όμ†Œ μ°Έμ‘°) νŽ˜μ΄μ§€ λ‘œλ“œλŠ” 항상 λ§€λ‹ˆνŽ˜μŠ€νŠΈ νŒŒμΌμ— μ €μž₯ν•œ 것과 λ³„κ°œμ˜ ν‚€λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

제 κ²½μš°μ—λŠ” {% compress %} λΈ”λ‘μ—μ„œ 인라인 μ½”λ“œλ₯Ό μ œκ±°ν•˜λ©΄ λ¬Έμ œκ°€ ν•΄κ²°λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

Compressor.cache 의 get_hexdigest ν•¨μˆ˜μ—μ„œ 데이터와 λ‹€μ΄μ œμŠ€νŠΈλ₯Ό 좔적할 수 μžˆμŠ΅λ‹ˆλ‹€. ν‘œμ€€ 좜λ ₯/μ›Ή μ„œλ²„ 였λ₯˜ λ‘œκ·Έμ—μ„œ λ‹¨μ„œλ₯Ό μ°ΎμœΌμ‹­μ‹œμ˜€.

도움이 되기λ₯Ό λ°”λžλ‹ˆλ‹€.

#154에 μˆ˜μ •λœ 사항 덕뢄에 개발 λ²„μ „μ—μ„œ μˆ˜μ •λ˜μ–΄μ•Ό ν•©λ‹ˆλ‹€.

인라인 블둝 내뢀에 μŠ€ν¬λ¦½νŠΈκ°€ ν¬ν•¨λœ 것이 문제인 것 κ°™μŠ΅λ‹ˆλ‹€. 이것은 μ΅œμ‹  개발 버전에 μžˆμ—ˆμŠ΅λ‹ˆλ‹€. κ°μ‚¬ν•©λ‹ˆλ‹€ @viotti

{% compress js inline %}
<script type="text/javascript" src="/static/js/pages/calculator.js"></script>

이 λ¬Έμ œλŠ” μ•žμ—μ„œ μ–ΈκΈ‰ν•œ κ²ƒμ²˜λŸΌ λ‹«ν˜€ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€. #154와 μ€‘λ³΅λ©λ‹ˆλ‹€.

μ•ˆλ…•ν•˜μ„Έμš”, μ €λŠ” 이 문제λ₯Ό κ²ͺκ³  μžˆμŠ΅λ‹ˆλ‹€. λ‚΄ settings.pyλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

### COMPRESSION - django_compressor
COMPRESS_ENABLED = True
COMPRESS_OFFLINE = True
COMPRESS_PARSER = 'compressor.parser.LxmlParser'
COMPRESS_CSS_FILTERS = [
    'compressor.filters.css_default.CssAbsoluteFilter',
    'compressor.filters.cssmin.CSSMinFilter',
    ]
COMPRESS_JS_FILTERS = [
    'compressor.filters.closure.ClosureCompilerFilter',
]

COMPRESS_CLOSURE_COMPILER_BINARY = 'java -jar /path/to/compiler.jar'

.html νŒŒμΌμ— μžˆλŠ” 인라인 js μ½”λ“œλ₯Ό μ œμ™Έν•˜κ³ λŠ” λͺ¨λ‘ μ œλŒ€λ‘œ μž‘λ™ν•©λ‹ˆλ‹€. λ‚΄ .htmlμ—μ„œ μ—°κ²°λœ μ—¬λŸ¬ CSS/js μ™ΈλΆ€ 파일이 μžˆμŠ΅λ‹ˆλ‹€. 이 λͺ¨λ“  것은 {% compress css/js %}둜 잘 μ••μΆ•λ˜μ–΄ μžˆμ§€λ§Œ .html νŒŒμΌμ— μΈμ‡„λœ λͺ¨λ“  js μ½”λ“œλ₯Ό μ••μΆ•ν•˜λ €κ³  ν•  λ•Œ(μ½”λ“œ 사이

μ—¬μ „νžˆ λ¬Έμ œκ°€ μžˆμŠ΅λ‹ˆλ‹€. dev λΆ„κΈ°μ—μ„œλ„ {{ STATIC_URL }}을 μ‚¬μš©ν•˜μ—¬ 16μ§„μˆ˜ 생성 ν”„λ‘œμ„ΈμŠ€κ°€ μ˜λ―Έκ°€ μ—†κ±°λ‚˜ manifest.json에 μ €μž₯된 16μ§„μˆ˜μ— ν•΄λ‹Ήν•˜μ§€ μ•ŠλŠ” μƒˆλ‘œμš΄ 16μ§„μˆ˜λ₯Ό μƒμ„±ν•˜λŠ” κ²ƒμœΌλ‘œ λ³΄μž…λ‹ˆλ‹€.

μ†”λ£¨μ…˜: μ••μΆ• jsκ°€ 블둝에 걸쳐 μžˆμ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, λ§ˆμŠ€ν„° ν…œν”Œλ¦Ώμ—μ„œ ν•œ 번 압좕을 μ‚¬μš©ν•˜κ³  각각이 μƒμ†ν•˜λŠ” ν…œν”Œλ¦Ώμ—μ„œ ν•œ 번 μ‚¬μš©ν•©λ‹ˆλ‹€. 단점: css 및 js에 λŒ€ν•΄ 각각 ν•˜λ‚˜κ°€ μ•„λ‹Œ 두 개의 http μš”μ²­. λ§ˆμŠ€ν„° js/cssλ₯Ό λͺ¨λ“  ν…œν”Œλ¦Ώμ— ν¬ν•¨ν•˜λ„λ‘ μ΄λ™ν•˜μ—¬ ν•˜λ‚˜λ‘œ 쀄일 수 μžˆμŠ΅λ‹ˆλ‹€.

ν…œν”Œλ¦Ώμ—μ„œ DRYλ₯Ό μ„ νƒν•˜κ³  http μš”μ²­μ„ μ€„μ΄λŠ” 것 쀑 ν•˜λ‚˜λ₯Ό μ„ νƒν•˜μ§€ μ•Šμ•„λ„ λœλ‹€λ©΄ 쒋을 κ²ƒμž…λ‹ˆλ‹€. :)

같은 일이 μΌμ–΄λ‚˜μ‹­μ‹œμ˜€. 압좕에 인라인 μ½”λ“œκ°€ μ—†μœΌλ©° λˆ„λ½λœ κ²ƒμœΌλ‘œ λ³΄κ³ ν•˜λŠ” ν‚€λŠ” μ‹€μ œλ‘œ manifest.json에 μžˆμŠ΅λ‹ˆλ‹€.
λ„λŒ€μ²΄ 무슨 일이 μΌμ–΄λ‚˜κ³  μžˆλŠ”μ§€ 정말 λͺ¨λ₯΄κ² μ–΄, λ‹€λ₯Έ μ‚¬λžŒμ΄ 아직도 이것을 가지고 μžˆλ‹ˆ? 이것에 λŒ€ν•œ λ‹€λ₯Έ λͺ¨λ“  λŒ“κΈ€μ€ 1λ…„ μ „μ˜ κ²ƒμž…λ‹ˆλ‹€.

@altryne : κΆŒν•œ 문제일 수 μžˆμŠ΅λ‹ˆλ‹€. μ›Ή μ„œλ²„/django ν”„λ‘œμ„ΈμŠ€μ— λ§€λ‹ˆνŽ˜μŠ€νŠΈλ₯Ό 읽을 수 μžˆλŠ” κΆŒν•œμ΄ μžˆλŠ”μ§€ ν™•μΈν•˜μ„Έμš”. 더 μžμ„Έν•œ 정보 μ—†μ΄λŠ” 더 이상 도움이 될 수 μ—†μŠ΅λ‹ˆλ‹€.

500νŽ˜μ΄μ§€ λΆ„λŸ‰μ˜ Djangoμ˜€μŠ΅λ‹ˆλ‹€. μ˜€ν”„λΌμΈ 압좕을 μ‚¬μš©ν•˜μ—¬ djangoλŠ” μ»¨ν…μŠ€νŠΈ 없이 500νŽ˜μ΄μ§€λ₯Ό λ Œλ”λ§ν•˜λ €κ³  ν–ˆμœΌλ©°, 이둜 인해 자체적으둜 500 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

이것은 정말 도움이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€:
http://chriskief.com/2013/09/18/django-compressor-offlinegenerationerror-and-500-html-handler500/

μ•ˆλ…•ν•˜μ„Έμš” μ—¬λŸ¬λΆ„, chriskief.com에 λŒ€ν•œ 링크가 도움이 λ˜μ—ˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ 그것은 λ‚˜λ₯Ό μœ„ν•΄ 문제λ₯Ό ν•΄κ²°ν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€. λ‚΄ μžλ°” μŠ€ν¬λ¦½νŠΈμ— "{{myvar}}"와 같은 django ν…œν”Œλ¦Ώ λ³€μˆ˜κ°€ μžˆλŠ” κ²ƒμœΌλ‘œ λ‚˜νƒ€λ‚¬μŠ΅λ‹ˆλ‹€. COMPRESS_OFFLINE_CONTEXT에 μΆ”κ°€ν•˜λŠ” 것을 μžŠμ—ˆμœΌλ―€λ‘œ ν‚€ λˆ„λ½ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. ν…œν”Œλ¦Ώ λ³€μˆ˜κ°€ μžˆλŠ” λͺ¨λ“  μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό μ••μΆ•κΈ°μ—μ„œ κΊΌλ‚΄λ©΄ λͺ¨λ“  것이 λ‹€μ‹œ 잘 μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€. ν‘œμ€€ django 였λ₯˜κ°€ μ•„λ‹ˆλΌ Apache "잘λͺ»λœ ꡬ성 νŽ˜μ΄μ§€"λ₯Ό ν‘œμ‹œν•˜λŠ” 500 였λ₯˜κ°€ λ°œμƒν•˜κΈ° 전에. COMPRESS_OFFLINE_CONTEXT의 λˆ„λ½λœ μ •μ˜λ§Œ λ¬Έμ œμΈμ§€ μ•„λ‹ˆλ©΄ {% url ... %}도 이 문제λ₯Ό μΌμœΌν‚€λŠ”μ§€ 아직 ν™•μ‹€ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λ‚΄ λ°°ν¬μ—μ„œ 이것을 보고 μžˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” κ·Έλ ‡κ²Œ 압좕을 μ‚¬μš©ν•œλ‹€

{% compress css %}
<link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
<link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap-social.css' %}">
<link rel="stylesheet" type="text/css" href="{% sass_src 'css/base.scss' %}">
{% endcompress %}

compressκ°€ sass_src νƒœκ·Έλ₯Ό μ²˜λ¦¬ν•  수 μ—†κΈ° λ•Œλ¬ΈμΌ 수 μžˆμŠ΅λ‹ˆκΉŒ?

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰