Symfony provides powerful tools for asset management, and among these tools are the Asset Mapper (importmap) and Symfony Encore. While both have their strengths, there are compelling reasons to choose Asset Mapper over Encore, particularly for projects seeking simplicity, speed, and minimal configuration. This article will guide you through the process of using the Asset Mapper, highlighting its benefits compared to Encore.
What is Asset Mapper (importmap)?
The Asset Mapper is a new tool in Symfony that allows you to manage JavaScript and CSS dependencies using a simple configuration and without the need for complex build steps. It uses the browser’s native ES module support to import dependencies directly, which can lead to faster load times and simpler asset management.
Why Use Asset Mapper Over Encore?
1. Simplicity and Minimal Configuration
The Asset Mapper is designed to work with minimal configuration. This makes it ideal for small to medium-sized projects or for developers who prefer to avoid the complexities of modern JavaScript build tools.
2. No Need for Node.js
The Asset Mapper does not require Node.js or NPM, reducing the overhead of managing these dependencies. This can simplify your development environment and avoid potential conflicts and issues related to Node.js.
3. Fast Compilation
The `bin/console asset-map:compile` command is generally faster and less resource-intensive than running Webpack builds, improving your development speed and efficiency.
4. Leveraging Native Browser Support
Using native ES module support can result in better performance and caching, as the browser handles the module imports directly. Additionally, the output of the asset-map:compile command is suffixed with a unique string (hash), ensuring that when you re-compile, the assets will not be cached by the browser. This effectively handles cache busting, ensuring users always receive the most up-to-date versions of your assets.
Setting Up Asset Mapper
Step 1: Install Symfony Asset Mapper
First, you need to install the Symfony Asset Mapper package:
composer require symfony/asset-mapper
Step 2: Configure Asset Mapper
Create a configuration file for the Asset Mapper:
// ./config/packages/asset_mapper.php
extension('framework', [
'asset_mapper' => [
'server' => false,
'paths' => [
'assets/',
],
],
]);
};
Step 3: Add Assets
Let's test everything is working as it should, place your JavaScript and CSS files in the assets directory (or any directory you specify in the configuration). For example, create a file assets/js/app.js:
// ./assets/js/app.js
import { greet } from './greet.js';
greet('Asset Mapper');
And assets/js/greet.js:
// ./assets/js/greet.js
export function greet(name) {
alert(`Hello, ${name}!`);
}
Now let's import some css, normally, you will probably have an `app.css` files somewhere which will be imported into your app.js file.
So seems pretty straightforward importing css in the app.js file, for example:
// ./assets/js/app.js
import './bootstrap.js';
import './styles/app.css';
import 'htmx.org'
Here we are importing a local JS and CSS file and an external JS package
HTMX.
But now, let's have a look at how we can import local CSS in how app.css file:
// ./assets/styles/app.css
@import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css");
@import url("./css/some-custom-css-file.css");
Here we are importing Bootstrap icons and a local CSS style sheet. Be sure to wrap all your css imports with the url() function, otherwise you will get a not found error, the reason this is happening is because when complied, asset mapper will suffix your file name with a unique hash, if you don't put the path in the url() function then the complier will load the suffixed file name, which won't exist.
Step 4: Compile Assets
Run the following command to compile your assets:
bin/console asset-map:compile
This command generates a manifest file that maps your assets to their respective paths.
Step 5: Include Assets in Twig Templates
In your Twig templates, use the asset_map function to include your assets:
{% block title %}My Beautiful Site Dot Com{% endblock %}
{% block stylesheets %}
{% endblock %}
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}
{% block body %}{% endblock %}