New in Symfony 6.4: AssetMapper Improvements


AssetMapper was introduced in Symfony 6.3 as a new & modern way to manage
JavaScript & CSS assets with zero build or external dependencies like Node.
In Symfony 6.4, we've improved it with a number of features you asked for.
The component is now also stable and protected by our BC promise!

Vendor Files Downloaded Locally

Contributed by Ryan Weaver
in #51786.

In Symfony 6.3, when you used the importmap:require command to "install" a 3rd-party
package, the final code referenced that file on the jsDelivr CDN. You could
pass a --download option to download the file locally, but it wasn't the
default.
In Symfony 6.4, the behavior is simpler: when you run importmap:require, the
file is always downloaded locally. Files are downloaded into an assets/vendor/
directory, which is ignored by default in the .gitignore file via the Flex
recipe. This is important because it allows the use of a CSP (Content Security
Policy) that only allows assets to be loaded from your own domain.
To download the files and populate the directory, run:

$ php bin/console importmap:install

This works very-much like composer install.

CSS Support

Contributed by Ryan Weaver
in #51543.

In Symfony 6.4, you can now import CSS files from JavaScript files:

// assets/app.js
import './styles/app.css';

In base.html.twig, the {{ importmap() }} function will output a link
tag for each CSS file it finds. And the system is smart: crawling every JavaScript
file imported by your entrypoint (app.js) looking for CSS imports. Importing
CSS isn't normally allowed in JavaScript modules, but AssetMapper makes it possible
by adding a "noop" entry to your importmap for each CSS file.
For 3rd party CSS files, you can use the importmap:require command:

$ php bin/console importmap:require bootstrap/dist/css/bootstrap.min.css

Then import it:

// assets/app.js
import 'bootstrap/dist/css/bootstrap.min.css';

Finally, while not technically part of Symfony 6.4, support for Sass and Tailwind
were added thanks to symfonycasts/sass-bundle and symfonycasts/tailwind-bundle.
You can even try using TypeScript with AssetMapper thanks to sensiolabs/typescript-bundle.

importmap:audit & importmap:outdated


Contributed by Hubert Lenoir
in #51650
and Maelan LE BORGNE
in #51845

When relying on 3rd-party JavaScript packages, it's important to learn about
any potential security vulnerabilities as soon as possible. In Symfony 6.4, the
importmap:audit command was added to do this:

$ php bin/console importmap:audit

This uses GitHub's advisory database to check for any known security issues
in the packages you're using. If any are found, you'll see a clear report and
the command will exit with a non-zero exit code.
Additionally, to check which packages have newer versions available, run:

$ php bin/console importmap:outdated

This works just like composer outdated. Packages can be updated with:

$ php bin/console importmap:update

Preloading & Entrypoints

Contributed by Ryan Weaver
in #51543.

One important part of using JavaScript modules is preloading the files you need
so that your browser can download them as soon as possible. In Symfony 6.3, you
could add a preload option to any entry in importmap.php to do this.
In Symfony 6.4, the mechanism is simpler and more robust. When calling
{{ importmap('app') }}, AssetMapper will find all JavaScript files that
app.js imports (recursively) and preload them. This means that every
JavaScript file needed to run your code will be preloaded with no extra work.

WebLink & CSS Preloading

Contributed by Ryan Weaver
in #51829.

The tags on your page are "render-blocking resources":
they block the rendering of your page until they are downloaded and parsed.
So, the sooner we can tell the browser to download them, the better.
In Symfony 6.4, if you install the symfony/web-link component, AssetMapper will
automatically add Link headers to your response that tell the browser to
preload all CSS files that will eventually be rendered via the {{ importmap() }}
function.

Asset Compiling Performance Improvements

Contributed by Simon André
in #52156.

AssetMapper doesn't require a build step, but it does still crawl through your
CSS and JavaScript files to find imports. AssetMapper has always had an
internal cache to avoid doing this on every request. But in Symfony 6.4, this
was greatly improved by avoiding the need to crawl non-CSS and JavaScript files.
Images, fonts, etc are now served directly without any overhead during development
or while running asset-map:compile.

Sponsor the Symfony project.