whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.02k stars 2.62k forks source link

Named modules / scripts #7600

Open AllanJard opened 2 years ago

AllanJard commented 2 years ago

I've the developer of the DataTables library and have been looking at how I can offer ES module versions of the library and run into two issues while doing so that I'd like to bring up for discussion (can I say how awesome it is that the WHATWG provide this ability to interact with the community btw - I've been doing open source for 15 years now, but I still love that some random person like me can write to the authors of the HTML spec!).

The two issues are:

  1. SRI for modules - Which I'm aware is something that has been discussed before such as #2382 and #5640
  2. Dependencies - We offer styling integration with e.g. Bootstrap and Bulma, which load a file and also need the core file.

I'm wondering if providing the ability to have named modules might be used to address both points. I've looked around and don't see anything on this topic already - apologies if I've missed it. I realise also that this will touch into TC39 territory.

My proposal is to add a name to the <script> tag which would be used as an alias that can be referred to in import statements. For example:

<script type="module" name="datatables.net" integrity="..." src="https://nightly.datatables.net/js/jquery.dataTables.mjs"></script>
<script type="module" name="datatables.net-bs5" integrity="..." src="https://nightly.datatables.net/js/jdataTables.bootstrap5.mjs"></script>
<script type="module">
import DataTables from 'datatables.net-bs5'; // internally this would refer to `datatables.net`, location of which is defined above

DataTables();
</script>

This named module approach would allow the initial load to check the SRI integrity (which I understand already works, although with the src repeated in the import statement), as well as dependency loading.

Edit I should also say that this method allows better portability. The Bootstrap 5 integration file could reference the absolute URL for the core file, but for anyone who wants to host it themselves, or I don't want to host it for the whole web, they'd need to change every source file. This way they just need to update the src attributes.

Yay295 commented 2 years ago

Would it work to give the script element an ID and then do document.getElementById('datatables.net').src?

domenic commented 2 years ago

Have you seen https://github.com/WICG/import-maps ?

AllanJard commented 2 years ago

@Yay295 - No it doesn't look like that will work unfortunately. As a quick experiment I tried:

    <script type="module" src="https://esm.sh/jquery@3.5.0" id="jquery"></script>
    <script type="module" src="https://nightly.datatables.net/js/jquery.dataTables.mjs" id="datatables.net"></script>
    <script type="module">
    const jqSrc = document.getElementById('jquery').src;
    const dtSrc = document.getElementById('datatables.net').src;

    import $ from jqSrc;
    import DataTables from dtSrc;

    DataTables($);

    $(document).ready( function () {
        var table = $('#example').DataTable();
    } );
    </script>

While jqSrc and dtSrc are strings, the import statement is throwing an error as it needs a static value. There is the possibility of using a dynamic import - that does make it possible, but the syntax is really awkward:

    const jqEl = document.getElementById('jquery').src;
    const dtEl = document.getElementById('datatables.net').src;

    const $ = (await import(jqEl)).default;
    const DataTables = (await import(dtEl)).default;

    DataTables($);

    $(document).ready( function () {
        var table = $('#example').DataTable();
    } );

It could perhaps be packages up into a little library so you can do im('datatables.net'), but you loose the commonality of the ES import syntax.

@domenic - Many thanks for the link, I hadn't seen that! That sounds very much like it would resolve the issues that I'm seeing with my ability to support ES modules for a client-side library like DataTables. Perhaps an import-map could operate with my suggestion of a name attribute (change it to map perhaps) to build an import map from the modules.

That said, the import-maps sound like a lot more engineering effort than being able to reference a Githubissues.

  • Githubissues is a development platform for aggregating issues.