Skip to content
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

Named modules / scripts #7600

Open
AllanJard opened this issue Feb 10, 2022 · 5 comments
Open

Named modules / scripts #7600

AllanJard opened this issue Feb 10, 2022 · 5 comments

Comments

@AllanJard
Copy link

AllanJard commented Feb 10, 2022

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 Does integrity="" intentionally not work on module <script>s? #2382 and Integration with import-attributes #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
Copy link
Contributor

Yay295 commented Feb 10, 2022

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

@domenic
Copy link
Member

domenic commented Feb 10, 2022

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

@AllanJard
Copy link
Author

@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 <script> element which does the src, CSP and integrity for us, albeit there would be no support for scopes and a programmatic API like proposed in import-maps.

I wonder if @guybedford might have any insights with his work on JSPM. Guy - we actually talked way back in 2015 about DataTables and jspm. I'm so behind the times... :).

@Jamesernator
Copy link

albeit there would be no support for scopes and a programmatic API like proposed in import-maps.

It's still fairly early stage, but the compartments proposal is meant for these sort've programmatic import use cases.

Shudi1234 added a commit to Shudi1234/Assignment2 that referenced this issue Aug 9, 2022
Refer to Named modules / scripts whatwg#7600, proposed to use the custom attributes in a script tag rather to add another new <Name> tag to the Script which would be used as an alias that can be referred to in import statements. This will able to save bandwidth by reduce another new attribute.
Shudi1234 added a commit to Shudi1234/Assignment2 that referenced this issue Aug 9, 2022
@javajosh
Copy link

Hello, I'm the author of the Literate Markdown authoring standard (github) which encourages use of module scripts.
It would be delightful to be able to import modules previously defined in the page!
You can see how this would be useful in this svg example.

The work-around is to generate separate module sub-resources from the single page, and then import them the usual way.
But this is not ideal because it's more complexity, and also it breaks the in-page mental model of the programmer.

Conceptually I think it is quite consistent with the mental model of the DOM that you can reference to previously defined elements and use them. You can do it would markup, and even with the body of scripts.
Importing a previously defined module just makes a lot of sense in my use case, and I can imagine it will make sense when more people start using native modules.

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

No branches or pull requests

5 participants