afnf.net

ブログエンジン(6) asset minify on-demand

blog-java1では、JavascriptとCSSの結合と最小化を行っています。独自の仕組み「asset minify on-demand」を作ったので、簡単に紹介します。

要件

  • 結合と最小化が自動的に行われること
  • 手動でも結合と最小化ができること
  • バージョン管理が自動的に行われること
  • 結合順序の制御ができること
  • デバッグ目的に、最小化がオンオフできること
  • 本番環境で無効化できること

方針

  • アセット更新時に処理するのではなく、JSPへのアクセス時に処理を行う
  • JSPのEL functionをトリガーとして、bash scriptを起動する
  • 結合と最小化はYUI Compressorを使用する
  • バージョン番号は別ファイルで管理する

ディレクトリ構造

ディレクトリ構造は以下のような感じです。

20140518_asset_structure

assets/blog.min.jsディレクトリのファイルが結合・最小化されて、main/webapp/static/blog.min.jsになります。

blog.min.js.versionは、バージョン番号が書かれたテキストファイルです。

結合と最小化の流れ

まず、blog.jspEL functionが解釈されます。

<script src="${as:url('/static/blog.min.js')}"></script>


EL functionは、blog.min.js.versionを読み取ります。

File verFile = new File(AppConfig.getWebappDir(), path + ".version");
if (verFile.exists()) {
  String versionStr = FileUtils.readFileToString(verFile);
  version = NumberUtils.toInt(StringUtils.trim(versionStr));
}


続いて、開発環境である場合は、生成対象であるblog.min.jsassets/blog.min.jsディレクトリ内のファイルと更新時刻を比較します。

long prevmod = destFile.lastModified();
Collection<File> files = FileUtils.listFiles(srcDir, null, false);
for (File file : files) {
  if (file.lastModified() > prevmod) {
    modified = true;
    break;
  }
}


更新されている場合は、assets/_minify.shを実行し、結合と最小化を行います。

function minify() {
  name=$1
  ext=${name##*.}

  pushd $SRC_DIR/$name > /dev/null

  cat *"$ext" > __tmp1
  if [ $? != 0 ]; then
    exit 1
  fi

  java -jar "$YUI_JAR" --charset utf-8 --type $ext __tmp1 -o __tmp2
  if [ $? != 0 ]; then
    exit 2
  fi

  ...


成功した場合は、バージョンファイルを更新します。

if (exitValue == 0) {
  File verFile = new File(AppConfig.getWebappDir(), path + ".version");
  version = version == null ? 0 : version + 1;
  versionMap.put(path, version);
  FileUtils.write(verFile, version.toString());
}


EL functionは、バージョン番号を加えたURLを返します。HTMLへの出力は以下のようになります。

<script src="/blog/static/blog.min.js;v=17"></script>

バージョン番号をクエリ文字列 "?v=17"とせず、パラメータ ";v=17"としているのは、プロキシサーバ(特にsquid)でキャッシュを有効にするためです。

まとめ

まあいい感じです。

似たようなことはGruntでもできるようなので、機会があれば調査したいです。

comments (0)

blog-java2 engine (build:2019-02-23 17:57 JST)