What’s the purpose of the HTML “nomodule” attribute for script elements if the default is text/javascript?
JavascriptHtmlEcmascript 6Es6 ModulesJavascript Problem Overview
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
?
Javascript Solutions
Solution 1 - Javascript
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:
>
>
>
> 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
).
Solution 2 - Javascript
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.
Solution 3 - Javascript
nomodule attribute
> As other answers mentioned, This Boolean attribute is set to indicate > that the script should not be executed in browsers that support ES2015 > modules — in effect, this can be used to serve fallback scripts to > older browsers that do not support modular JavaScript code.
Now let's understand with an example.
I'm using es6/ES2015 features and need to include core.js to run application in IE browser and other major browser like chrome, firefox, safari are supporting es6/ES2015 features. You can see total vender size will be 150kb for IE browser.
<script src="core.js"></script> // around 45kb after gzip
<script src="obserPoly.js></script> // around 5kb after gzip
<script src="vender.js></script> // around 100kb after gzip
why should I load core.js & obserpoly.js (45kb+5kb = 50kb) in other browsers. I have used nomodule attribute with my script and it worked like a champ. Now, Core.js and obserPoly.js scripts load in IE browsers only.
<script nomodule src="core.js"></script> // around 45kb after gzip
<script nomodule src="obserPoly.js></script> // around 5kb after gzip
<script src="vender.js></script> // around 100kb after gzip