Skip to content

[AssetMapper] importmap() function imports all entry points #54377

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jmariller opened this issue Mar 22, 2024 · 6 comments
Open

[AssetMapper] importmap() function imports all entry points #54377

jmariller opened this issue Mar 22, 2024 · 6 comments

Comments

@jmariller
Copy link

Symfony version(s) affected

7.0.0

Description

So I am not sure if this is really a bug or if it is intended to work like this, but when using the AssetMapper function importmap() with a given entrypoint, I would expect not to see other entrypoints defined in importmap.php to be part of the compiled <script type="importmap">.

How to reproduce

  1. Add a few entrypoints in importmap.php (for example login.js, admin.js, app.js)
  2. Use one of the entrypoints in a twig template, like so: {% block importmap %}{{ importmap('login') }}{% endblock %}
  3. When looking into the generated source I can see in <script type="importmap"> not only an entry for login.js but for all entrypoints

Possible Solution

No response

Additional Context

No response

@smnandre
Copy link
Member

For now i'm not sure it is possible, when rendering the importmap, to know which scripts may be later imported... as some of them can be lazy-loaded (stimulus controller), or needed in a dynamic HTML part (via turbo, ajax, ...)

So we could maybe hide the other entrypoint files, but you would still see in the importmap all the app's controllers & vendors.

This is inside the importmap, but only the scripts that do need to run should be listed in the <link rel="modulepreload" scripts, is this not working for you ?

Does this "shared" importmap create a problem in your project ?

@jmariller
Copy link
Author

Thank you for your answer. So our concern is more security-related, because our application has public and private sections, and we do have scripts for both sections - now even though there is not really sensitive data in the scripts for the private sections we would rather avoid exposing those scripts in the public sections.

@smnandre
Copy link
Member

I understand, but sadly i don't have any solution for this..

I can tell you that anyone that want to see your scripts can, as you probably have a manifest.json in your asset directoy. But i must admit this is not the same thing as having the links in the source code.

I you needed to, i guess you could render the importmap in a template, and remove from there the lines you want to hide before rendering it on your page ?

@Kocal
Copy link
Member

Kocal commented Oct 9, 2024

What about support multiple importmap.php files? Or multiple "apps"?

In my own case, where I want a distinct separation between the frontend and the administration part (a bit for the same reasons than OP, but more like to prevent "dependencies leaking" across two different apps), maybe we can adapt the importmap.php to support multiples apps (here app and admin) ?:

return [
    'app' => [
        'path' => './assets/app.js',
        'entrypoint' => true,
    ],
    'admin' => [
        'path' => './assets/admin.js',
        'entrypoint' => true,
    ],
    '@hotwired/stimulus' => [
        'version' => '3.2.2',
    ],
    '@symfony/stimulus-bundle' => [
        'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
    ],
    '@hotwired/turbo' => [
        'version' => '8.0.5',
    ],
    'leaflet' => [
        'version' => '1.9.4',
    ],
    'leaflet/dist/leaflet.min.css' => [
        'version' => '1.9.4',
        'type' => 'css',
    ],
    '@symfony/ux-leaflet-map' => [
        'path' => './vendor/symfony/ux-leaflet-map/assets/dist/map_controller.js',
    ],
    'codemirror' => [
        'version' => '...',
    ],
];

to:

return [
    'app' => [
        'app' => [
            'path' => './assets/app.js',
            'entrypoint' => true,
        ],
        '@hotwired/stimulus' => [
            'version' => '3.2.2',
        ],
        '@symfony/stimulus-bundle' => [
            'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
        ],
        '@hotwired/turbo' => [
            'version' => '8.0.5',
        ],
        'leaflet' => [
            'version' => '1.9.4',
        ],
        'leaflet/dist/leaflet.min.css' => [
            'version' => '1.9.4',
            'type' => 'css',
        ],
        '@symfony/ux-leaflet-map' => [
            'path' => './vendor/symfony/ux-leaflet-map/assets/dist/map_controller.js',
        ],
    ],
    'admin' => [
        'admin' => [
            'path' => './assets/admin.js',
            'entrypoint' => true,
        ],
        'codemirror' => [
            'version' => '...',
        ],
    ]
];

Ofc, in this configuration, we should adapt importmap:* commands, to be able to run sf console importmap:require my-dependency --app=admin etc...

In bonus, we would want to configure Stimulus controllers per apps too.

WDYT?

@althaus
Copy link
Contributor

althaus commented Mar 14, 2025

Just stumbled upon this issue with the exact same scenario while refactoring an outdated app.

I'd like to split a frontend part and an admin section. They are even running on complete different frontend tech stacks and mixing those up just feels bad for my inner Monk. So multiple files or "apps" would be great to keep things clean. ❤

@ThomasLandauer
Copy link
Contributor

I just added the current behavior to the docs symfony/symfony-docs#20789 - so if this ever gets changed, don't forget to delete that again :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants