咱们知道有3种方式在浏览器里加载js代码:javascript
1:<script>...</script>之间嵌入js代码**
2:<script src='xx.js'></script> 经过src引入外部js文件**
3:加载js代码如workers(例如 web worker或者service worker)html
由于js module和纯粹的js脚本代码有不一样之处(例如js module里的变量只在本module里面可见,不会加到global,因此也不会挂在到window上),为了能加载js module代码,上面提到的3种机制都会有相应的改变。接下来就具体来看一下,浏览器加载module代码的机制:java
1: js module的加载依然有上面提到的三种方式
咱们先来讲前2种,也是咱们最熟悉的经过<script>标签的方式:web
<script src="./index.js" type="module"></script> <script type="module"> console.log('in html') </script>>
以module的方式加载,须要把<script>标签的type设置为‘module’,当没有设置type值的时候,默认是"text/javascript"。浏览器
2:defer和async
咱们知道<script>标签还有defer和async这2个布尔型的属性,他们能够决定js代码的执行顺序,也会有document的解析产生影响,如今咱们来看一下他们会对咱们的模块加载产生怎样的影响:
defer
咱们先来复习一下defer的特性:
1:带defer的js代码不会阻碍页面解析,js代码的下载和页面的解析是同步进行的,js代码的执行要等页面解析完成以后再开始。
2:加载多个带defer的js文件,会按照顺序执行。例以下面的一段代码,a.js执行完以后才会下载b.js和执行b.js.async
<script src="./static/js/a.js" defer></script> <script src="./static/js/b.js" defer></script>
3: defer只对带src的从外部加载js文件的<script>有效,对于内嵌js代码的<script>...</script>是不起做用的。code
<script type='module'> 用module方式加载的js,默认带有defer的属性,即具有defer的特效,上面提到的前2点都同样,只是第三点不一样:即便内嵌js代码的module,也具有defer的属性。例如:htm
<!--第一执行index.js--> <script src="./index.js" type="module"></script> <!--第二执行内嵌module--> <script type="module"> console.log('in html') </script> <!--第三执行main.js--> <script src="./main.js" type="module"></script>
async
先来复习一下async的特性:
1: 带有async的<script>的js文件下载不会阻塞页面解析,可是js文件一旦下载完,就会当即执行,假如这时候页面解析尚未完成,这就会阻塞页面解析。
2:多个带有async的<script>的js文件的执行顺序是没法肯定的。
那若是type='module'又同时带有async的<script>文件的执行特性是怎样的呢?由于前面咱们说了type='module'至关于默认带有defer,可是咱们知道defer和async是不一样的。结论就是带有async的模块加载按照async的特性执行,例如:ip
<script src="./index.js" type="module" async></script> <script src="./main.js" type="module" async></script>
究竟是先执行index.js仍是main.js,这里是不能肯定的。同步
3:加载module的时候文件路径
与加载常规的js代码不一样的是,模块加载对文件路径有要求,下面4种是合法的:
1:以 / 开头的根目录
2:以 ./ 开头的当前路径
3:以 ../开头的父路径
4:一个URL路径
好比:
<!--如下为合法的文件路径--> <script src="/module1.js" type="module"></script> <script src="./module2.js" type="module"></script> <script src="../module/module3.js" type="module"></script> <script src="https://www.xxxx.com/module/module4.js" type="module"></script> <!--如下为不合法的文件路径--> <script src="module5.js" type="module"></script> <script src="module/module5.js" type="module"></script>