How And Why I Use Symfony Asset Mapper (Importmap) Over Encore
2 months ago
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

<?php

declare(strict_types=1);

use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator): void {
    $containerConfigurator->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/[email protected]/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:


<!DOCTYPE html>
<html lang="EN">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}My Beautiful Site Dot Com{% endblock %}</title>
    {% block stylesheets %}
    {% endblock %}

    {% block javascripts %}
        {% block importmap %}{{ importmap('app') }}{% endblock %}
    {% endblock %}
</head>
<body>
   {% block body %}{% endblock %}
</body>
</html>


Symfony's Asset Mapper (importmap) offers a simpler, faster, and more efficient way to manage your JavaScript and CSS dependencies compared to Symfony Encore. By leveraging native browser capabilities and reducing the need for complex build tools, the Asset Mapper is an excellent choice for projects looking to streamline their asset management process.

For projects that do not require the full power and flexibility of Webpack, the Asset Mapper provides a lightweight and effective alternative. Try it out in your next Symfony project to experience the benefits firsthand!