ES6模块懒加载

ES6的模块化使用import导入模块,使用webpack打包的时候,webpack会把所有通过import导入的模块,代码打包到bundle里面。
示例:

import _ from 'lodash-es'
var arr = [1,2,3,4]
console.log('webpackJsonp',webpackJsonp)
setTimeout(()=>{
    console.log("_",_.chunk(arr,2))
},5000)

//输出结果
//webpackJsonp [Array(2), push: ƒ]
//_ (2) [Array(2), Array(2)]

从webpackJsonp这个对象可以看到,lodash模块会立马被加载。

import()实现懒加载

但是其实我们并不需要立马把全部模块加载,我们希望我们希望webpack打包的时候只打包我们会立马用到的代码,而不需要立马用到的模块,可以单独打包成一个js文件,当需要用到这个模块的时候才去加载这个模块的代码,这样可以减少我们第一次加载的bundle的文件提交,提高传输速度。
此时用ES6的模块懒加载就能实现我们的期望。
使用import('模块路径')实现懒加载。

因为setTimeout函数是异步,所以我们并不需要立马加载lodash模块,可写成懒加载的形式:

// 修改异步模块的文件名:
// const { chunk } = await import(/* webpackChunkName:"lodash" */"lodash-es");

var arr = [1,2,3,4]
console.log('webpackJsonp1',webpackJsonp)
setTimeout( async()=>{
    const _ = await import('lodash-es')
    console.log('webpackJsonp2',webpackJsonp)
    console.log("_",_.chunk(arr,2)) 
},5000)

//输出结果
//webpackJsonp1 [push: ƒ]
//index.js:5 webpackJsonp2 [Array(2), push: ƒ]
//index.js:6 _ (2) [Array(2), Array(2)]

打开控制台可以看到,lodash打包的代码在5秒后才会被加载进来。
import()是异步,返回的是一个promise,这种懒加载的形式是ES6的草案阶段,但是webpack可以支持。原理就是webpack会把最终使用jsonp的方式远程加载这个模块。

如何处理es6模块懒加载和tree-shaking兼容?
tree-shaking是依赖于es6模块化的import和export静态分析依赖来实现的,而import()的方式是属于动态加载模块,就会导致tree-shaking对这部分的模块不起作用。因此以上webpack打包出来的异步模块是把整个lodash打包了,体积很大。
因此可以通过创建新模块来引入需要异步加载模块,写成静态加载的形式即可。

//新建util.js

//util.js:
export { chunk } from "lodash-es";

//index.js
var arr = [1,2,3,4]
setTimeout( async()=>{
    const chunk = await import('./other')
},5000)

tree-shaking发现了import导入other模块,通过AST语法分析到index依赖于other模块,因此会进一步分析other模块里面的依赖,发现里面的模块化是es6标准,因此tree-shaking能进行进一步优化,但是由于other模块是异步模块,webpack会把优化后的代码单独保存到一个js文件,当需要的时候再去加载这个文件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值