読者です 読者をやめる 読者になる 読者になる

webassetsがよさげ

Python Django JavaScript

webassetsはWebアプリケーションのJavaScript/CSSの管理ユーティリティライブラリ。もっとわかり易く言うと、複数のJavaScriptファイルをまとめたり、圧縮してくれたり、URLに変更日時のタイムスタンプを付けてくれたりする便利ライブラリ。

「よさげ」って言うより、個人的な感覚ではこれはかなりの優良ライブラリって感じがするが、いつの間にかJavaScriptとかCSSに関しては周回遅れもいいとこって状態になってしまっていたので自信がない。もしかしたら、同様のライブラリがあるかもしれない・・・

インストールは例によってpipで、

$ pip install webassets

Djangoでしか試していないけど基本的な使い方としては、まずsettings.pyに、

INSTALLED_APPS = (
    'myproject.myapp',
    # ...省略
    'django_assets'
    'django.contrib.auth',
    'django.contrib.contenttype',
    # ...省略
)

のようにdjango_assetsを追加。

そのうえで、Djangoアプリケーションモジュールの中にassets.pyを作る。例えばmyproject.myappというアプリケーションだとすると、myproject/myapp/assets.pyというファイルを作る。内容は、

# -*- coding: utf-8 -*-                                          
from django_assets import Bundle, register

js = Bundle('js/my1.js', 'js/my2.js', filters='jsmin', output='js/packed.js')
register('js_all', js)

のようなもの。テンプレートでは、

{% load assets %}
{% assets "js_all" %}
<script type="text/javascript" src="{{ ASSET_URL }}"></script>  
{% endassets %}

のようにassetsタグライブラリを追加して、webassets経由で出力するJavaScriptをASSET_URLで読み込むようにする。

Bundleに関しては上のコードだけで、「js/my1.jsとjs/my2.js2というJavaScriptファイルに、jsminというフィルターをかけて、js/packed.jsというファイル名で出力する」は想像できると思う。詳しくはオフィシャルのドキュメントのBundleのページを見ていただきたい。

最初戸惑う点は、上の例のように相対パスJavaScriptファイルを指定した場合、どこがパスの起点になるかってこと。

この点に関しては、Django標準のMEDIA_ROOT, MEDIA_URL変数を使う。オフィシャルのドキュメントのsettingsの項を参照。MEDIA_ROOTやMEDIA_URLを設定していないとASSETS_URLを使った時に残念なことになるので、

# settings.py
MEDIA_ROOT = '/path/to/application/public/dir'
MEDIA_URL 'http://example.com/static/'

のように何かしら指定しないといけない。これらの設定を行うと最終的に、

<script type="text/javascript" src="http://example.com/static/js/packed.js?1298477948"></script>

といったHTMLが出力される。

上ではjsminフィルターを使っているが、YUI compressorを使う場合には、settings.pyに

# settings.py
YUI_COMPRESSOR_PATH = '/path/to/yuicompressor-2.4.2.jar'

のようにYUI_COMPRESSOR_PATHを設定した上で、assets.pyでfilterにyui_jsを指定する。

# -*- coding: utf-8 -*-                                          
from django_assets import Bundle, register

js = Bundle('js/my1.js', 'js/my2.js', filters='yui_js', output='js/packed.js')
register('js_all', js)

webassetsはSymfony2で公式に採用されるであろうAsseticライブラリの紹介スライドを見ていて知ったのだが、webassetsを知った瞬間、PHPとかSymfony2とかAsseticとかどうでもよくなったよ。ありがとうSymfony2、ありがとうPHP