type(默认text/javascript)
该属性定义 script 元素包含或src引用的脚本语言。属性的值为 MIME 类型(媒体类型);
如果没有定义这个属性,脚本会被视作 JavaScript。 如果 MIME 类型不是 JavaScript 类型,则该元素所包含的内容会被当作数据块而不会被浏览器执行。 如果 type 属性为module,代码会被当作 JavaScript 模块。
1、application/json
浏览器则不会把script里面的内容当做js来执行,我们在script标签中可以直接写json格式数据
<script id="json-script" type="application/json">
{
"data": [
{
"a": 1,
"b": 2
}
],
"total": 1
}
</script>
此时定义的json数据获取,我们可以通过js
<script>
const node = document.getElementById("json-script");
const jsonStr = JSON.parse(node.innerText);
console.log(jsonStr);
</script>
2、module
type=module 用来支持 es6 的模块功能
<script type="module">
import { func } from "./utils.js";
document.body.innerHTML = func("abc");
</script>
// utils.js
export function func(text) {
return text;
}
当脚本使用 import 指令时,浏览器会自动请求并加载相关的 JS 文件。
📢 script[type=”module”]会受到cors策略的限制
<!-- 这个脚本不会执行,因为跨域资源共享限制 -->
<script type="module" src="https://….now.sh/no-cors"></script>
当然啦,type=module存在部分低端浏览器不支持的情况,这就需要我们做兼容啦。常见的写法
<scrip type="module" src="app.js"></scrip>
<scrip nomodule src="other.js"></scrip>
使用 <script type="module"> 可以在让支持 esmodule 的浏览器运行,不支持 esmodule 的浏览器忽略。
使用 <script nomodule> 可以让支持 esmodule 的浏览器忽略,不支持 esmodule 的浏览器运行。
3、importmap
我们已经熟悉从npm导入包的方式,但是需要一个构建步骤编译代码使其能够在浏览器中运行。
这个问题由import maps解决了。从本质上讲,它允许将导入指定器映射到相对或绝对的URL上,有助于控制模块的解析,而不再需要应用构建步骤。
规范:
搭配type="module"一起用,这个script 标签必须放在 document 中的中第一个 <script type="module">标签之前(最好是在<head>中),以便在进行模块解析之前对它进行解析。此外,目前每个 document 只允许有一个 import map,未来可能会取消这一限制。
在 script 标签内,一个JSON对象被用来指定document中 script 所需的所有必要的模块映射。一个典型的 import map 的结构如下所示。
<script type="importmap">
{
"imports": {
"react": "https://cdn.skypack.dev/react@17.0.1",
"react-dom": "https://cdn.skypack.dev/react-dom",
"square": "./modules/square.js",
"lodash": "/node_modules/lodash-es/lodash.js"
}
}
</script>
<script type="module">
import { cloneDeep } from 'lodash';
const objects = [{ a: 1 }, { b: 2 }];
const deep = cloneDeep(objects);
console.log(deep[0] === objects[0]);
</script>
在 import map 中出现包并不意味着它一定会被浏览器加载。任何没有被页面上的 script 使用的模块都不会被浏览器加载,即使它存在于import map中。
使用同一模块的多个版本,
<script type="importmap">
{
"imports": {
"lodash@3/": "https://unpkg.com/lodash-es@3.10.1/",
"lodash@4/": "https://unpkg.com/lodash-es@4.17.21/"
}
}
</script>
通过使用作用域,也可以用同一个导入指定符来指代同一个包的不同版本。这允许我们在一个给定的作用域内改变导入指定符的含义。
<script type="importmap">
{
"imports": {
"lodash/": "https://unpkg.com/lodash-es@4.17.21/"
},
"scopes": {
"/static/js": {
"lodash/": "https://unpkg.com/lodash-es@3.10.1/"
}
}
}
</script>
有了这种映射,在/static/js路径下的任何模块,在导入语句中引用lodash/指定器时,将使用https://unpkg.com/lodash-es@3.10.1/,而其他模块将使用https://unpkg.com/lodash-es@4.17.21/。
检测 import map支持
if (HTMLScriptElement.supports && HTMLScriptElement.supports('importmap')) {
// import maps is supported
}
对于不支持的浏览器,可以试试polyfill。我们所需要做的就是在 import map 脚本之前在HTML文件中包含es-module-shim脚本。
<script async src="https://unpkg.com/es-module-shims@1.3.0/dist/es-module-shims.js"></script>
参考:https://blog.csdn.net/qq449245884/article/details/126133582;MDN