Automatisches Versionieren von JavaScript- und CSS-Dateien in Magento

Einführung

In Magento können JavaScript und CSS-Dateien können über Layoutupdates hinzugefügt werden:

<layout version="0.1.0">
    <default translate="label" module="page">
        <label>All Pages</label>
        <block type="page/html" name="root" output="toHtml" template="page/3columns.phtml">
            <block type="page/html_head" name="head" as="head">
                <action method="addJs"><script>prototype/prototype.js</script></action>
                <action method="addJs" ifconfig="dev/js/deprecation"><script>prototype/deprecation.js</script></action>
                <action method="addJs"><script>lib/ccard.js</script></action>
                <action method="addJs"><script>prototype/validation.js</script></action>
                <action method="addJs"><script>scriptaculous/builder.js</script></action>
               ...
                <action method="addCss"><stylesheet>css/styles.css</stylesheet></action>
                <action method="addItem"><type>skin_css</type><name>css/styles-ie.css</name><params/><if>lt IE 8</if></action>
                <action method="addCss"><stylesheet>css/widgets.css</stylesheet></action>
                <action method="addCss"><stylesheet>css/print.css</stylesheet><params>media="print"</params></action>

                <action method="addItem"><type>js</type><name>lib/ds-sleight.js</name><params/><if>lt IE 7</if></action>
                <action method="addItem"><type>skin_js</type><name>js/ie6.js</name><params/><if>lt IE 7</if></action>
            </block>
		</block>
	</default>
<layout>

Im HTML-Source-Code ergibt sich dann dieser Code innerhalb innerhalb des <head>-Tags:

<link rel="stylesheet" type="text/css" href="http://local.magento1/skin/frontend/default/default/css/styles.css" media="all" />
<link rel="stylesheet" type="text/css" href="http://local.magento1/skin/frontend/base/default/css/widgets.css" media="all" />
<link rel="stylesheet" type="text/css" href="http://local.magento1/skin/frontend/default/default/css/print.css" media="print" />
<script type="text/javascript" src="http://local.magento1/js/prototype/prototype.js"></script>

<script type="text/javascript" src="http://local.magento1/js/lib/ccard.js"></script>
<script type="text/javascript" src="http://local.magento1/js/prototype/validation.js"></script>
<script type="text/javascript" src="http://local.magento1/js/scriptaculous/builder.js"></script>
...

<script type="text/javascript" src="http://local.magento1/js/varien/menu.js"></script>
<script type="text/javascript" src="http://local.magento1/js/mage/translate.js"></script>
<script type="text/javascript" src="http://local.magento1/js/mage/cookies.js"></script>
...

Unter:

System > Configuration > Advanced > Developer > JavaScript Settings > Merge JavaScript Files und
System > Configuration > Advanced > Developer > CSS Settings > Merge CSS Files (beta)

kann man einstellen, dass die Dateien jeweils gebündelt werden. Das sieht dann so aus:

<link rel="stylesheet" type="text/css" href="http://local.magento1/media/css/bfa479ccd15402213bd41ff35e0b00d0.css" media="all" />
<link rel="stylesheet" type="text/css" href="http://local.magento1/media/css/6d59b55f253b49c875b2b60fac3c74e5.css" media="print" />
<script type="text/javascript" src="http://local.magento1/media/js/4b842d3161d04a9a93e038c198647dec.js"></script>

Das ist schon mal deutlich kompakter und kann sehr viele HTTP-Requests an den Server ersparen. Die Darstellung des Shop-Frontends im Browser kann damit beschleunigt werden.

Durch das Senden von geeigneten Expire-Headern kann man nun verhindern, dass diese Dateien bei jeder Seitendarstellung neu geladen werden. Diese Dateien werden dann im Browsercache gespeichert.

<FilesMatch "\.(gif|jpg|js|css)$">
	ExpiresActive On
	ExpiresDefault "access plus 10 years"
</FilesMatch>

Problem

Zum Problem wird das allerdings, wenn sich Änderungen in den CSS oder JS-Dateien ergeben. Der von Magento generierte MD5-Hash, aus dem die Dateinamen der Dateien entstehen, berücksichtigen nicht den Inhalt der Dateien, sondern nur den Dateinamen.

Lösung

Abhilfe schafft hier meine Extension Aoe_JsCssTstamp. Diese Extension erweitert den Dateinamen der Bundledatei um den Zeitstempel der jüngsten darin enthaltenen Datei. Sobald sich eine Datei aus dem Bundle ändert, erhält die Bundle-Dateien einen neuen Timestamp, der dann auch im Quelltext erscheint. Die Browser erkennen, dass es sich um eine neue Datei handelt und fordern diese Datei neu an anstatt sie auch dem Browsercache zu lesen. Somit kann man Änderungen an CSS- und JS-Dateien deployen, die sofort Effekt in allen Browsern haben, und dabei trotzdem Expire-Headers verwenden, um zu verhinden, dass gleiche Dateien mehrfach vom Server geladen werden.

Im HTML-Markup sieht das dann so aus:

<link rel="stylesheet" type="text/css" href="http://local.magento1/media/css/bfa479ccd15402213bd41ff35e0b00d0.1291842738.css" media="all" />
<link rel="stylesheet" type="text/css" href="http://local.magento1/media/css/6d59b55f253b49c875b2b60fac3c74e5.1291842737.css" media="print" />
<script type="text/javascript" src="http://local.magento1/media/js/4b842d3161d04a9a93e038c198647dec.1299020182.js"></script>

Download

Meine Extension zum Download (inkl. modman-Konfigurationsdatei, oder einfach im Hauptverzeichnis entpacken)

Aoe_JsCssTstamp (v. 0.0.1)

Weitere Links

 

Recent Comments

Zend Certified Engineer (ZCE)
TYPO3 Certified Integrator
Magento Certified Developer PLUS