如果默认值为 text/javascript,那么脚本元素的 HTML “nomodule” 属性有什么用?

What’s the purpose of the HTML “nomodule” attribute for script elements if the default is text/javascript?

我不太明白为什么在支持ES6模块的新浏览器中存在nomodule属性。

在 HTML 5 中,type 属性是可选的并且 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".

它不会默认为 <script type="module" src="module.js"></script>。这个默认值改变了吗?如果不是,为什么 nomodule 是必要的?我可以只使用 <script src="bundle.js"></script> 而不使用 nomodule 吗?

purpose of the nomodule attribute is to cause newer browsers that support module scripts 忽略特定的 script 元素:

The nomodule attribute is a boolean attribute that prevents a script from being executed in user agents that support module scripts.

规范 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.

这就是它的工作原理。

In HTML 5, the type attribute is optional and defaults to text/javascript… Has this default changed?

默认值没有改变——仍然是 text/javascript。但是 type 属性现在也可以具有值 module,这意味着浏览器仍将其解析为 text/javascript 并执行——但也特别是作为 module script.

If not, why would nomodule be necessary?

为了防止支持模块脚本的新浏览器执行仅适用于不支持模块脚本的旧浏览器的脚本,如上例所示。

Can I just use <script src="bundle.js"></script> without nomodule?

是的,如果 bundle.js 不使用模块。如果它使用模块,你想把 type=module 放在它上面(在这种情况下,旧浏览器会忽略它,因为它们不识别 typemodule 值)。

无模块属性

nomodule 属性是一个布尔值属性,用于指示浏览器哪些支持某个脚本标签不需要的模块已加载

nomodule 属性的目的是为不支持 <script type="module"> 的旧浏览器提供 备份脚本 ,因此将忽略它​​们。由于旧版浏览器既不支持 <script type="module"> 也不支持 nomodule 属性,因此可能会出现以下情况:


较新的浏览器,支持<script type="module"> & <script nomodule type="text/javascript">

  • 浏览器可以加载并执行<script type="module">脚本
  • 浏览器识别 nomodule 属性并且不加载 <script nomodule type="text/javascript">

旧版浏览器支持<script type="module"> & <script nomodule type="text/javascript">

  • 浏览器将忽略 <script type="module">,因为它的实现无法处理它。不会下载和执行任何脚本。
  • 浏览器将忽略 nomodule 属性,并将继续下载并执行 <script nomodule type="text/javascript"> 脚本。

无模块属性

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.

下面我们通过一个例子来理解。

我正在使用 es6/ES2015 功能,需要在 IE 浏览器和 chrome、firefox、safari 等其他主流浏览器中包含 core.js 到 运行 应用程序es6/ES2015 个特征。您可以看到 IE 浏览器的总供应商大小为 150kb。

<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 

为什么我要在其他浏览器中加载 core.js & obserpoly.js (45kb+5kb = 50kb)。我在我的脚本中使用了 nomodule 属性,它的效果非常好。现在,Core.js 和 obserPoly.js 脚本仅在 IE 浏览器中加载。

<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