前端的代码分片,或者说是按需加载,本质上是由于前端页面越来越复杂,代码体积越来越大,程序员需要对页面资源的加载做细粒度的控制。按需加载当然是好东西,但是会让页面逻辑变得更加复杂。好在webpack
出现,让按需加载变得简单多了。
我们来做一个简单的demo,完整代码
demo的功能很简单,单击一个按钮,然后去加载一个js文件并执行。
index.html文件:
<button id="btn">load script</button>
index.js文件
document.getElementById('btn').addEventListener('click',function(){
require.ensure([],()=>{
let hello = require('./Hello').default;
hello();
},'Hello')
})
Hello.js文件
export default function hello(){
alert('hello.')
}
在 click 的事件处理函数中,通过 require.ensure
标记分割点,然后加载Hello.js
并赋值给变量hello
,最后调用该方法。这里需要说一下的是require.ensure
的第三参数,是这个分片chunk的name。如果不加这个参数,默认会以chunkid
来命名该文件。这个参数在开发环境还是很有用的,毕竟1.js
的文件名,让人很难定位文件。
由于 ES2015 Loader spec 定义了 import()
方法来在运行时动态的加载javascript
文件,所以webpack也把import()
作为split code
的分割点。
如果想用酷炫的import()
语法,还需要安装一个插件:npm i babel-plugin-syntax-dynamic-import --save-dev
。然后,就可以把上面的 index.js
文件改成:
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
的第三个参数),这样打包出来的文件都是用数字来标示的,非常难以区分,在开发环境下,会使定位错误变的更加困难。
此外,这两种语法在引用文件时,文件路径都不可以是表达式。例如:
require.ensure([],()=>{
let path = './Hello';
let hello = require(path).default;
hello();
},'Hello')
这样会报错,无法正常加载文件。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。