前端的代碼分片,或者說是按需加載,本質上是因爲前端頁面愈來愈複雜,代碼體積愈來愈大,程序員須要對頁面資源的加載作細粒度的控制。按需加載固然是好東西,可是會讓頁面邏輯變得更加複雜。好在webpack
出現,讓按需加載變得簡單多了。javascript
咱們來作一個簡單的demo,完整代碼
demo的功能很簡單,單擊一個按鈕,而後去加載一個js文件並執行。html
index.html文件:前端
<button id="btn">load script</button>
index.js文件java
document.getElementById('btn').addEventListener('click',function(){ require.ensure([],()=>{ let hello = require('./Hello').default; hello(); },'Hello') })
Hello.js文件webpack
export default function hello(){ alert('hello.') }
在 click 的事件處理函數中,經過 require.ensure
標記分割點,而後加載Hello.js
並賦值給變量hello
,最後調用該方法。這裏須要說一下的是require.ensure
的第三參數,是這個分片chunk的name。若是不加這個參數,默認會以chunkid
來命名該文件。這個參數在開發環境仍是頗有用的,畢竟1.js
的文件名,讓人很難定位文件。git
因爲 ES2015 Loader spec 定義了 import()
方法來在運行時動態的加載javascript
文件,因此webpack也把import()
做爲split code
的分割點。程序員
若是想用酷炫的import()
語法,還須要安裝一個插件:npm i babel-plugin-syntax-dynamic-import --save-dev
。而後,就能夠把上面的 index.js
文件改爲:github
document.getElementById('btn').addEventListener('click',function(){ import('./Hello').then((Hello) => { let hello = Hello.default; hello(); }).catch(err => console.log('Failed to load moment', err)) })
import()
支持promise語法,因此能夠用catch
來處理加載文件引發的異常。可是,它也有它的弱點,import()
沒法給這個文件命名(相似於require.ensure
的第三個參數),這樣打包出來的文件都是用數字來標示的,很是難以區分,在開發環境下,會使定位錯誤變的更加困難。web
此外,這兩種語法在引用文件時,文件路徑都不能夠是表達式。例如:npm
require.ensure([],()=>{ let path = './Hello'; let hello = require(path).default; hello(); },'Hello')
這樣會報錯,沒法正常加載文件。