0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

画像やJSをロード、"AssetMapper"

Last updated at Posted at 2023-12-09

Symfony Component Advent Calendar 2023の10日目の記事です。

画像やJSをロード、"AssetMapper"

AssetMapperはアセットのマッピングと、公開領域へのファイルの生成を行うコンポーネントです。
Symfony 6.3から導入された新しいコンポーネントですが、実はSymfonyでのフロントエンドの扱いが大きく変わるコンポーネントとなっており、Symfony公式ドキュメントではWebpack Encoreではなく、AssetMapperを推奨しています。

インストール

composer require symfony/asset-mapper

assetsディレクトリへのアクセスは別途Assetコンポーネントが必要です。また、当然ながらTwigも必要です。

composer require symfony/asset symfony/twig-pack

インストールすると、以下のファイルが作成されます。

  • assets/app.js
  • assets/styles/app.css
  • config/packages/asset_mapper.yaml
  • importmap.php

また、templates/base.html.twigが更新されます。

{% block javascripts %}
+     {{ importmap('app') }}
{% endblock %}

使い方

AssetMapperは主にふたつの機能があります。一つがassetsディレクトリに置いたファイルへアクセス・公開する機能、もう一つが、importMapを使ったJavaScriptのインポートです。

Assetへのアクセス

assetsディレクトリ内の画像などのURLは asset('{assetsディレクトリからの相対パス}') を使うことで自動的に生成されます。

<img src="{{ asset('images/sample.png') }}">
<!-- /assets/images/sample-{バージョン文字列}.png -->

バージョンの文字列はファイルが更新されるたびに新しい文字列になります。

開発環境では特になにもせずにこの記述でアクセスできますが、本番環境ではassetsディレクトリのファイルを公開領域であるpublicに移動される必要があります。移動させる場合は以下のコマンドを実行します。

bin/console asset-map:compile

実行すると、publicにバージョン文字列を付与した状態でファイルがコピーされます。

ImportMap

開発環境では、JavaScriptは templates/base.html.twigに追記された{{ importmap('app') }}によって自動で読み込まれます。本番環境では先ほどのbin/cosole asset-map:compileを実行すればおなじくpublic領域に移動できます。

例:

assets/sample.js
import Person from "./person.js";

export default class {
    hello() {
        const person = new Person()
        return person.hello('PHPer')
    }
}
assets/person.js
export default class {
    hello = name => 'Hello ' + name;
}
assets/app.js
import Sample from "./sample.js"

console.log(Sample.prototype.hello())

ブラウザのコンソール

Hello PHPer

サードパーティ製のパッケージの読み込み

サードパーティ製はimport時にCDNでアクセスすれば読み込めます。

import { Alert } from 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/+esm';

ですが、めんどくさいです。AssetMapperはnpmパッケージ上のサードパーティ製パッケージの情報をimportmap.phpに追記することで、HTML出力時に自動的にパッケージをimportします。追記する場合は、以下のコマンドを使うと簡単に追記できます。

bin/console importmap:require bootstrap
importmap.php
return [
    'app' => [
        'path' => './assets/app.js',
        'entrypoint' => true,
    ],
    'bootstrap' => [
        'version' => '5.3.0',
    ],
];

このようにすれば、import時の記述はこのようにできます。

import { Alert } from 'bootstrap';

さて、上記のコマンドを実行してなぜサードパーティのパッケージにアクセスできるかというと、{{ importmap('app') }}の出力が以下のようになっているからです。

<script type="importmap">
{
    "imports": {
        "app": "/assets/app-f389ccbe276b2074b6a0fa768c244921.js",
        "/assets/sample.js": "/assets/sample-248cf7faeba93e0400a862a6d448a0da.js",
        "/assets/person.js": "/assets/person-b64cf9aac50c2f6da0b6a2ba027b68e6.js",
        "bootstrap": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/+esm",
    }
}
</script>

これにより、import時に該当のモジュールを解決することができます。
同様にサードパーティのCSSもapp.jsにimportすれば利用できます。

上記のようにimportmapが作成され、CDN経由で該当のスクリプトをロードします。ここまでのコマンドを実行していただくとわかるのですが、packages.jsonは作られません。つまり、このコンポーネントでサードパーティ製のパッケージを利用するのであれば、npmは不要です。

なぜかSymfony7になるとapp.jsで読み込んだjsの中のimport(上記例だとperson.js)が読み込まれない模様。修正が入ると思います。

まとめ

今回はAssetMapperについて紹介しました。以前紹介したSymfony UXもWebpack EncoreとAssetMapperのどちらでも動作するようになっており、今後の動向が非常に気になるコンポーネントです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?