Skip to content

Merge / expose importmaps somehow? #38

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
matthiask opened this issue Dec 17, 2024 · 2 comments
Open

Merge / expose importmaps somehow? #38

matthiask opened this issue Dec 17, 2024 · 2 comments

Comments

@matthiask
Copy link

Hey

Sorry in advance for my rambling.

I have been looking into using ES modules and for django-prose-editor; I do not want to load individual Tiptap and ProseMirror modules from esm.sh or something like that because I do not want to depend on an external resource and because it's really really slow (because there are so many modules involved)

I could build an ES module and expose that, but then I have all the problems with the ManifestStaticFilesStorage and people having to configure their own static files storage and enable JS module aggregation and whatnot, and that's complex and annoying to do -- I do not want the setup of the editor to be that annoying in projects.

So, I have discovered importmaps, as have you! Importmaps are great, the problem is that they only exist in singular today; proposals are going around for supporting several importmaps. But, browser support isn't great anyway, and requiring something which isn't even here yet is even less great. If browsers supported multiple importmaps I could just ship my own importmap for django-prose-editor (using object-based media!). But, that's not possible obviously right now.

Are you interested in collaboratively designing and/or developing a way of building an importmap from multiple sources? I think something like this could be a good fit for django-esm. If I understand the docs and code correctly you're only using package.json and the static file finders now, but you aren't exposing hooks to third party apps to add to the importmap -- users of django-esm have to configure everything themselves. So, it's mostly for consuming their own scripts and scripts from node_modules if I understand correctly, and not really for third party packages?

It's quite probable I'm misunderstanding something, but I wanted to ask before following my NIH impulse again.

@codingjoe
Copy link
Owner

Hi @matthiask,

Thanks for reaching out about this topic. I just gave a talk about the state of ESM at the Berlin Django meetup, and I am rather invested in getting the show on the road.

Sadly, I noticed, that more often than not, JavaScript packages are the issue. Not browsers. ESM loading and importmap have been part of Baseline2023. JavaScript packages sadly often don't come as ESM or define proper exports. However, at least the bigger frameworks usually do support it. So the key for me was to simply drop as many dependencies as I could ;)

Next on my agenda is actually to build a custom static file storage. I want to post-process JS files and bundle dependencies using ESbuild. This would make this package pretty versatile, since everything would just be transpiled into ESM.

Injecting or merging importmaps from python packages, could be implemented, but I didn't have a use case yet. You can ship ESM, via your packages with no problem. I am doing so already in django-s3file. However, my packages typically come dependency free.

I also don't believe it's a good idea to maintain a global importmap. If an interface, like Django admin, wants to use importmap, it can do so. A mixed approach, might be better. But then form media (should you need external dependencies) are still something to figure out.

Long story short, there's still much work to be done. I continue trying out some new ideas during the holidays.

I'll keep you posted on my progress!

Cheers!
Joe

@matthiask
Copy link
Author

A quick heads up: I have a very hacky experiment here showing what I'm trying to achieve:
https://github.com/matthiask/django-js-asset/compare/mk/importmaps

from django.forms import Media
from django.test import TestCase

from js_asset.js import JS
from js_asset.media import ExtendedMedia, ImportMapImport


class MediaTest(TestCase):
    def test_importmap(self):
        media_ab = Media(js=["a.js", "b.js"])
        media_bc = Media(js=["b.js", "c.js"])
        media_ac = Media(js=["a.js", "c.js"])

        extended_a = ExtendedMedia(
            [JS("a.js"), ImportMapImport("library-a", "/static/library-a.abcdef.js")]
        )
        extended_b = ExtendedMedia(
            [ImportMapImport("htmx.org", "/static/htmx.org.012345.js"), JS("b.js")]
        )

        merged = media_ab + media_bc + media_ac + extended_a + extended_b

        self.assertEqual(
            str(merged),
            """\
<script type="importmap">{"imports": {"htmx.org": "/static/htmx.org.012345.js", "library-a": "/static/library-a.abcdef.js"}}</script>
<script src="/static/a.js"></script>
<script src="/static/b.js"></script>
<script src="/static/c.js"></script>""",
        )

        self.assertEqual(
            str(merged),
            str(extended_a + media_ab + media_ac + extended_b + media_bc),
        )

It doesn't map to what you're doing in django-esm I think, but it shows how the forms.Media object could be leveraged to not only collect CSS and JavaScript assets but also importmap entries and maybe also other stuff. I could also imagine adding some postprocessing facilities such as compressing or bundling to the Media class, but I'm personally less interested in that.

Do you have any new insights or experiments to share? No problem if not (obviously!). Thanks for your time :)

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

No branches or pull requests

2 participants