I can't seem to find an answer to my question about whether I should include files in a <script>
tag when using ES6 modules or if a browser will request them automatically? If so, how does it resolve the path?
In a comment you've said:
I know that there's no support yet. My question is about how it'll behave when implemented
There wasn't when we first posted this question and answer, but there is now. And it matches what I'd previously described was provisionally specified: You use type="module"
:
<script src="mod.js" type="module"></script>
You only do that for the entry point, not for the modules the entry point references via import
(more below).
From the WHAT-WG specification:
The type attribute allows customization of the type of script represented:
- ...
- Setting the attribute to an ASCII case-insensitive match for the string "module" means that the script is a module script, to be interpreted according to the JavaScript Module top-level production. ...
- ...
...
Classic scripts and module scripts may either be embedded inline or may be imported from an external file using the
src
attribute, which if specified gives the URL of the external script resource to use.
The modules' dependencies will be resolved and automatically fetched, you don't list them in their own script
tags. Just the entry point.
Note that you can serve modules to module-enabled browsers and also serve transpiled bundles to non-module-enabled browsers by using the nomodule
attribute:
The
nomodule
attribute is a boolean attribute that prevents a script from being executed in user agents that support module scripts. This allows selective execution of module scripts in modern user agents and classic scripts in older user agents, as shown below. Thenomodule
attribute must not be specified on module scripts (and will be ignored if it is).
And since any browser that supports modules supports ES2015 features at least (probably more as well), that means you can serve native class
and arrow function and such code in modules, and transpiled code in non-module bundles, so you get native performance from native engines.
Later, the spec says:
To resolve a module specifier given a URL base URL and a JavaScript string specifier, perform the following steps. It will return either a URL record or failure.
- Apply the URL parser to specifier. If the result is not failure, return the result.
- If specifier does not start with the character U+002F SOLIDUS (/), the two-character sequence U+002E FULL STOP, U+002F SOLIDUS (./), or the three-character sequence U+002E FULL STOP, U+002E FULL STOP, U+002F SOLIDUS (../), return failure.
NOTE: This restriction is in place so that in the future we can allow custom module loaders to give special meaning to "bare" import specifiers, like
import "jquery"
orimport "web/crypto"
. For now any such imports will fail, instead of being treated as relative URLs.
So, if the module is a peer of the file loading it, start the module specifier with ./
(src="./myfile.js"
or import ... from "./myfile.js"
). Plain module specifiers with no path at all are reserved for import maps (should they ever be supported unflagged in browsers other than Chromium-based ones).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With