咱們知道有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>