Skip to content

Angular 18のpublicフォルダ内アセット参照方法

問題概要

Angular 18ではワークスペース構成のアプリケーションで、/publicフォルダに配置したアセット(画像など)が参照できない問題があります。v17まではsrc/assetsフォルダが標準でしたが、v18では次の構造に変更されています:

workspace-name

 ├── projects
 │    │
 │    └── application-name
 │         │
 │         ├── public   ← 新しいアセット配置場所
 │         └── src

期待される動作:

  • publicフォルダ内のファイルがビルド時に出力ディレクトリにコピーされる
  • テンプレートから<img src="...">で正しく参照できる

実際の現象:

  • アセット参照が失敗する
  • ビルド時にpublicフォルダの内容が出力ディレクトリにコピーされない
  • angular.jsonの初期設定で期待通り動作しない

根本原因

Angular 18のデフォルト設定では、ワークスペース構成の場合にangular.jsonのアセット設定パスが不完全です。初期設定は以下ですが、ワークスペース内のアプリケーションに対して相対パスが適切に解決されません

json
"assets": [
 {
  "glob": "**/*",
  "input": "public" // 問題のある部分
 }
]

解決策

基本設定(単一アプリケーション)

publicフォルダ直下にimgフォルダを作成し画像logo.pngを配置:

public/
 └── img/
      └── logo.png

テンプレートでの参照:

html
<!-- public/をパスに含めない -->
<img src="img/logo.png" alt="ロゴ">

ワークスペース構成修正法

ワークスペース配下のアプリケーションでは、angular.jsonを修正:

json
"assets": [
 {
   "glob": "**/*",
   "input": "projects/アプリケーション名/public", // 完全パス指定
   "output": "/"
 }
]

修正後、ビルド時にpublicフォルダの内容が出力ディレクトリのルートにコピーされます。

assetsフォルダを維持する方法

publicフォルダ内にassetsフォルダを作成してv17形式を維持:

public/
 └── assets/
      └── images/
           └── icon.png

angular.jsonassets設定に追記:

json
"assets": [
 {
   "glob": "**/*",
   "input": "public"
 },
 {
   "glob": "**/*",
   "input": "src/assets", // 旧形式フォルダも利用可能
   "output": "/assets"
 }
]

テンプレート参照:

html
<img src="assets/images/icon.png" alt="アイコン">

CSS/SCSS内での参照方法

CSSファイルからアセットを参照する場合、パスに^プレフィックスを使用:

css
/* src/styles.css */
@font-face {
  font-family: 'CustomFont';
  src: url('^public/fonts/custom-font.woff2') format('woff2');
}

^はプロジェクトルートからの絶対パスを意味します。

よくある落とし穴と解決法

注意点1: ビルド後にアセットが存在しない

ビルド後もアセットがdistに存在しない場合:

  1. angular.jsonのパスが正しいか確認
  2. 入力パスがprojects/アプリ名/public形式になっているか確認
  3. サーバー再起動(ng serveの再実行)

パス参照規則

  • ルート相対パス: /assets/image.pngpublic/assetsが存在する場合)
  • 相対パス: img/photo.jpgpublic/img/photo.jpgが存在する場合)
  • 絶対パスを使用する場合、デプロイ環境でのベースURLに注意

エラー発生時のチェックリスト

  1. publicフォルダの位置が正しいか
  2. angular.jsonの修正後にビルド再実行したか
  3. 参照パスにpublic/が含まれていないか
  4. ファイル拡張子が正しいか(.jpg, .pngなど)

設定のカスタマイズ例

特定ファイルのみをコピー

json
{
  "glob": "*.{jpg,png,webp}",
  "input": "public/images",
  "output": "/img"
}

出力フォルダ変更

json
{
  "glob": "**/*",
  "input": "public",
  "output": "static-assets" // dist/static-assets/に出力
}

まとめ

Angular 18の正しいアセット参照では:

  1. ワークスペース構成ではangular.jsonアプリケーション相対パスを設定
  2. 参照時はpublic/フォルダ名をパスに含めない
  3. 従来のassetsフォルダ形式を維持する場合はpublic/assetsを作成
  4. CSS内参照には^プレフィックスを使用

デフォルト設定が完全ではないため、ワークスペース利用時は必ずangular.jsonのパスを確認してください。これによりpublicフォルダのアセットが正しくビルドされ、参照可能になります。