webpack異步加載的原理
把一些js模塊給獨立出一個個js文件,然後使用這個 模塊的時候,webpack會構造script dom元素,瀏覽器會自動幫我們發起請求,去請求這個js文件
使用了異步加載,異步的文件會單獨打包出來,瀏覽器運行的時候並不會一開始就請求出來,而是在調用這個文件的時候瀏覽器纔會對此js文件發起請求.
舉個例子:當我們項目用到統計圖的時候,初始的時候並不會調用chart插件,只有點擊了生成統計圖按鈕纔會顯示出來,這個時候我們就可以利用webpack的異步加載,用戶點擊了按鈕,瀏覽器纔會去下載chart.js.
下面這段代碼是常規的操作,在點擊的時候,纔去加載chart,等chart加載完成後,在利用chart的對象去執行我們的操作
Btn.click(function() {
//獲取head
var head = document.getElementsByTagName('head')[0];
//創建 <script>
var script = document.createElement('script');
script.src = "http://www.xxx.com/chart.js"
//添加到head節點中
head.appendChild(script);
})
那麼用webpack要怎麼操作呢?
// a.js
Btn.click(function() {
require.ensure([], function() {
var chart = require('./chart.js') //chart.js放在我們當前目錄下
})
})
[]:require.ensure所依賴的其他 異步加載的模塊,例如:如果a,c,d都是異步加載的,a中需要c,d,那麼a下載之前,就要先下載c,d
// a.js
//require.ensure(['c','d'], function() {...})
分析一下:require.ensure這個函數是一個代碼分離的分割線,表示 回調裏面的require 是我們想要進行分割出去的,即require(’./chart.js’),把chart.js分割出去,形成一個 webpack打包的單獨js文件。
如果ensure裏面寫一些同步的require的話,是不會單獨被打包
實踐一下:
我們創建async.js,sync.js和utils.js
// index.html中添加一個按鈕
<button id="btn">btn</button>
// sync.js
export const radom = (x) => {
return parseInt(Math.radom()*10)*x;
}
//utils.js
export const add = (x,y) => {
return x+y;
}
// async.js // 點擊按鈕異步加載utils.js
import './sync'; // 引用同步的模塊
document.getElementById('btn').onclick = ()=>{
require.ensure([], function() {
var bwork = require('./util')
console.log(bwork.add(1,2));
})
}
最後在入口的文件引用async.js
import './js/async'; // 引用異步模塊
...
ReactDOM.render(
...,
document.querySelector('.container-index')
);
打包的結果(1.js文件是異步文件單獨提出來的結果):
最後在瀏覽器中運行index.html
可以看到,只有在點擊按鈕的時候,瀏覽器纔會請求1.js文件