前提
parcelでCSS, JavaScriptをbundleしているSpringBootのWebアプリケーション
CSSではurl()
の構文で画像を呼び出している
.hoge {
background-image: url(../img/icon.png);
}
こちらをparcelでbundleすると、SCSSからCSSに変換される
.hoge {
background-image: url(/icon.869a98d2.png);
}
- build時に
bundle.css
と同じディレクトリに画像が配置されるため、絶対パス指定になっている - キャッシュのためにファイル名にハッシュが追加されている (公式)
困りごと
SpringBootのpropertyファイルで、アプリケーションにコンテキストパスを追加した
server.servlet.context-path=/foo
この変更により、エンドポイントが以下のように変わる
CSS等の静的ファイルの配置場所も同様
一方、上述の通り、bundle後のCSSは画像をルートから絶対パスで指定している
.hoge {
background-image: url(/icon.869a98d2.png);
}
そのため、CSSから画像を呼び出す際にコンテキストパスが加味されず
/foo
なしの http://localhost:8080/icon.869a98d2.png を見に行ってしまう
しかしコンテキストパス追加によって画像の配置URLは変わっているため、404となる
対応
parcelの起動コマンドに--public-url
オプションを追加した
parcel build assets/js/index.js --out-dir target/classes/static --out-file bundle.js
↓
parcel build assets/js/index.js --out-dir target/classes/static --out-file bundle.js --public-url ./
これにより、bundle後のCSSで画像を呼び出す際、ルートからの絶対パス指定がされなくなる
.hoge {
background-image: url(icon.869a98d2.png);
}
foo配下にcssと画像が配置されている状態であるため、
bundle.cssからurl(/icon.869a98d2.png)
と指定しても取得できないが、
相対パス指定でurl(icon.869a98d2.png)
とすれば問題なく取得ができる
foo
|--- bundle.css
|--- icon.869a98d2.png
なおpublic-url /foo
とすれば以下のようになるため、絶対パス指定を防ぐ設定というわけではない
こちらでも動くが、propertyファイルで行っているコンテキストパスの設定と同期を取る必要があり、二重管理のリスクが発生する
またテスト環境ではコンテキストパスを変えたい等の場合も面倒ごとが増える
そのため相対パスでの指定が吉と思われる
.hoge {
background-image: url(/foo/icon.869a98d2.png);
}
参考
Set the public URL to serve on (parcel公式)
https://en.parceljs.org/cli.html#set-the-public-url-to-serve-on