The purpose of the nomodule
attribute is to cause newer browsers that support module scripts to ignore a particular script
element:
The nomodule
attribute is a boolean attribute that prevents a script from being executed in user agents that support module scripts.
The spec has a good example:
This example shows how to include a module script for modern user agents, and a classic script for older user agents:
<script type="module" src="app.js"></script>
<script nomodule src="classic-app-bundle.js"></script>
In modern user agents that support module scripts, the script
element with the nomodule
attribute will be ignored, and the script
element with a type of "module
" will be fetched and evaluated (as a module script). Conversely, older user agents will ignore the script
element with a type of "module
", as that is an unknown script type for them — but they will have no problem fetching and evaluating the other script
element (as a classic script), since they do not implement the nomodule
attribute.
So that’s how it works.
In HTML 5, the type
attribute is optional and defaults to text/javascript
… Has this default changed?
The default hasn’t changed—it’s still text/javascript
. But the type
attribute can now also have the value module
, which means browsers still parse and execute it as text/javascript
—but also specifically as a module script.
If not, why would nomodule
be necessary?
It’s needed in order to prevent new browsers that support module scripts from executing scripts intended only for old browsers that don’t support module scripts, as in the above example.
Can I just use <script src="bundle.js"></script>
without nomodule
?
Yes, if bundle.js
doesn’t use modules. If it uses modules, you want to put type=module
on it (in which case old browsers ignore it since they don’t recognize the module
value for type
).