模块(Module)简介

什么是模块

  • 一个模块就是一个文件,一个脚本就是一个模块
  • 模块之间可以相互加载
  1. export 关键字标记了可以从当前模块外部访问的变量和函数。
  2. import 关键字允许从其他模块导入功能。
// 📁 sayHi.js
export function sayHi(user) {
  alert(`Hello, ${user}!`);
}
// 📁 main.html
<!doctype html>
<script type="module">
  import {sayHi} from './say.js';

  document.body.innerHTML = sayHi('John');
</script>

在这里插入图片描述


核心模块功能

  • 始终使用"use strict"
  • 模块级作用域:每个模块都有自己独立的作用域
    hello.js 尝试使用在 user.js 中声明的变量 user,失败了:
#index.html
<!doctype html>
<script type="module" src="user.js"></script>
<script type="module" src="hello.js"></script>
//user.js
let user = "John";
//hello
alert(user); // no such variable (each module has independent variables)
  • 在浏览器中,每个 <script type="module"> 也存在独立的顶级作用域
<script type="module">
  // 变量仅在这个 module script 内可见
  let user = "John";
</script>

<script type="module">
  alert(user); // Error: user is not defined
</script>
  • 模块代码仅在第一次导入时被解析
    如果在某个位置修改了导入的代码,那么其它的模块也可以看到就这个修改(包含源文件)
// 📁 alert.js
alert("Module is evaluated!");
// 在不同的文件中导入相同的模块

// 📁 1.js
import `./alert.js`; // Module is evaluated!

// 📁 2.js
import `./alert.js`; // (什么都不显示)
  • import.meta 对象包含关于当前模块的信息
    它的内容取决于其所在的环境。在浏览器环境中,它包含当前脚本的 URL,或者如果它是在 HTML 中的话,则包含当前页面的 URL。
<script type="module">
  alert(import.meta.url); // 脚本的 URL(对于内嵌脚本来说,则是当前 HTML 页面的 URL)
</script>
  • 在一个模块中,"this"是 undefined
<script>
  alert(this); // window
</script>

<script type="module">
  alert(this); // undefined
</script>

浏览器特定功能

  • 模块脚本总是延迟的
  1. 下载外部模块脚本 <script type="module" src="..."> 不会阻塞 HTML 的处理,它们会与其他资源并行加载。
  2. 模块脚本会等到 HTML 文档完全准备就绪(即使它们很小并且比 HTML 加载速度更快),然后才会运行。
  3. 保持脚本的相对顺序:在文档中排在前面的脚本先执行。
// 第二个脚本会先于第一个脚本执行
<script type="module">
  alert(typeof button); // object:脚本可以“看见”下面的 button
  // 因为模块是被延迟的(deferred,所以模块脚本会在整个页面加载完成后才运行
</script>

// 相较于下面这个常规脚本:

<script>
  alert(typeof button); // button 为 undefined,脚本看不到下面的元素
  // 常规脚本会立即运行,常规脚本的运行是在在处理页面的其余部分之前进行的
</script>

<button id="button">Button</button>
  • Async 适用于内联脚本
<!-- 所有依赖都获取完成(analytics.js)然后脚本开始运行 -->
<!-- 不会等待 HTML 文档或者其他 <script> 标签 -->
<script async type="module">
  import {counter} from './analytics.js';

  counter.count();
</script>
  • 外部脚本
  1. 具有相同 src 的外部脚本仅运行一次
<!-- 脚本 my.js 被加载完成(fetched)并只被运行一次 -->
<script type="module" src="my.js"></script>
<script type="module" src="my.js"></script>

  1. 从另一个源(例如另一个网站)获取的外部脚本需要 CORS header,如我们在 Fetch:跨源请求 一章中所讲的那样。换句话说,如果一个模块脚本是从另一个源获取的,则远程服务器必须提供表示允许获取的 header Access-Control-Allow-Origin
<!-- another-site.com 必须提供 Access-Control-Allow-Origin -->
<!-- 否则,脚本将无法执行 -->
<script type="module" src="http://another-site.com/their.js"></script>
  • 不允许裸模块
    在浏览器中,import 必须给出相对或绝对的 URL 路径
import {sayHi} from 'sayHi'; // Error,“裸”模块
// 模块必须有一个路径,例如 './sayHi.js' 或者其他任何路径
  • 兼容性
<script type="module">
  alert("Runs in modern browsers");
</script>

<script nomodule>
  alert("Modern browsers know both type=module and nomodule, so skip this")
  alert("Old browsers ignore script with unknown type=module, but execute this.");
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值