I am not clearly understanding why the nomodule
attribute exists in the new browsers that support ES6 modules.
In HTML 5, the type
attribute is optional and defaults to text/javascript
:
The type attribute gives the language of the script or format of the data. If the attribute is present, its value must be a valid MIME type. The charset parameter must not be specified. The default, which is used if the attribute is absent, is "text/javascript".
It doesn't default to <script type="module" src="module.js"></script>
. Has this default changed? If not, why would nomodule
be necessary? Can I just use <script src="bundle.js"></script>
without nomodule
?
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 necessary in order to prevent new browsers that support module scripts from executing a script that’s 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‘d want to put type=module
on it (in which case old browsers will ignore it since they don’t recognize the module
value for type
).
nomodule attribute
The nomodule attribute is a boolean attribute which is used to indicate to a browser which does support modules that a certain script tag doesn't need to be loaded.
The purpose of the nomodule attribute is to have a backup script for older browser who don't support the <script type="module">
and thus will ignore them. Because the older browser neither support the <script type="module">
nor the nomodule attribute the following scenarios can occur:
Newer browsers, supports <script type="module">
& <script nomodule type="text/javascript">
- The browser can load and execute the
<script type="module">
script
- The browser recognizes the nomodule attribute and doesn't load
<script nomodule type="text/javascript">
.
Older browsers, don't support <script type="module">
& <script nomodule type="text/javascript">
- The browser will ignore the
<script type="module">
since its implementation cannot process this. No script will be downloaded and executed.
- The browser will ignore the nomodule attribute since and will continue to dowload and execute the
<script nomodule type="text/javascript">
script.