详解webpack import()动态加载模块踩坑


Posted in Javascript onJuly 17, 2018

import

webpack根据ES2015 loader 规范实现了用于动态加载的import()方法。

这个功能可以实现按需加载我们的代码,并且使用了promise式的回调,获取加载的包。

在代码中所有被import()的模块,都将打成一个单独的包,放在chunk存储的目录下。在浏览器运行到这一行代码时,就会自动请求这个资源,实现异步加载。

这里是一个简单的demo。

import('lodash').then(_ => {
  // Do something with lodash (a.k.a '_')...
 })

可以看到,import()的语法十分简单。该函数只接受一个参数,就是引用包的地址,这个地址与es6的import以及CommonJS的require语法用到的地址完全一致。可以实现无缝切换【写个正则替换美滋滋】。

并且使用了Promise的封装,开发起来感觉十分自在。【包装一个async函数就更爽了】

然而,以上只是表象。

只是表象。

我在开发的时候就遇到了问题。场景是这样的:一个对象,存储的是各级的路由信息,及其对应的页面组件。为减少主包大小,我们希望动态加载这些页面。

同时使用了react-loadable来简化组件的懒加载封装。代码如下所示。

function lazyLoad(path) {
 return Loadable({
  loader: () => import(path),
  loading: Spin,
 });
}

然后我就开始开心的在代码中写上lazyLoad('./pages/xxx')。果不其然,挂了。浏览器表示,没有鱼丸没有粗面,也不知道这个傻逼模块在哪里。

于是我查看了官方文档,发现有一个黄条提示。

详解webpack import()动态加载模块踩坑

emmm,看来问题出在这里了。

这个现象其实是与webpack import()的实现高度相关的。由于webpack需要将所有import()的模块都进行单独打包,所以在工程打包阶段,webpack会进行依赖收集。

此时,webpack会找到所有import()的调用,将传入的参数处理成一个正则,如:

import('./app'+path+'/util') => /^\.\/app.*\/util$/

也就是说,import参数中的所有变量,都会被替换为【.*】,而webpack就根据这个正则,查找所有符合条件的包,将其作为package进行打包。

详解webpack import()动态加载模块踩坑

因此,如果我们直接传入一个变量,webpack就会把 (整个电脑的包都打包进来[不闹]) 认为你在逗他,并且抛出一个WARNING: Critical dependency: the request of a dependency is an expression。

所以import的正确姿势,应该是尽可能静态化表达包所处的路径,最小化变量控制的区域

如我们要引用一堆页面组件,可以使用import('./pages/'+ComponentName),这样就可以实现引用的封装,同时也避免打包多余的内容。

另外一个影响功能封装的点,是import()中的相对路径,是import语句所在文件的相对路径,所以进一步封装import时会出现一些麻烦。

因为import语句中的路径会在编译后被处理成webpack命令执行目录的相对路径.

友情链接:https://webpack.js.org/api/module-methods/#import

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
来自国外的14个图片放大编辑的jQuery插件整理
Oct 20 Javascript
js静态方法与实例方法分析
Jul 04 Javascript
JavaScript子类用Object.getPrototypeOf去调用父类方法解析
Dec 05 Javascript
上传图片预览JS脚本 Input file图片预览的实现示例
Oct 23 Javascript
JS简单获取日期相差天数的方法
Apr 24 Javascript
一文搞懂ES6中的Map和Set
May 20 Javascript
ES6 let和const定义变量与常量的应用实例分析
Jun 27 Javascript
Vue data的数据响应式到底是如何实现的
Feb 11 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
Apr 07 Javascript
Vue element-ui父组件控制子组件的表单校验操作
Jul 17 Javascript
微信小程序wx.getUserInfo授权获取用户信息(头像、昵称)的实现
Aug 19 Javascript
vue中element 的upload组件发送请求给后端操作
Sep 07 Javascript
vue-router中的hash和history两种模式的区别
Jul 17 #Javascript
JS使用tween.js动画库实现轮播图并且有切换功能
Jul 17 #Javascript
SVG实现时钟效果
Jul 17 #Javascript
JS中实现隐藏部分姓名或者电话号码的代码
Jul 17 #Javascript
基于D3.js实现时钟效果
Jul 17 #Javascript
vue生成token并保存到本地存储中
Jul 17 #Javascript
vue脚手架搭建项目的兼容性配置详解
Jul 17 #Javascript
You might like
PHP遍历二维数组的代码
2011/04/22 PHP
Sublime里直接运行PHP配置方法
2014/11/28 PHP
使用Microsoft Ajax Minifier减小JavaScript文件大小的方法
2010/04/01 Javascript
IE本地存储userdata的一个bug说明
2010/07/01 Javascript
分享精心挑选的12款优秀jQuery Ajax分页插件和教程
2012/08/09 Javascript
异步安全加载javascript文件的方法
2015/07/21 Javascript
WEB前端开发框架Bootstrap3 VS Foundation5
2016/05/16 Javascript
jQuery实现点击弹出背景变暗遮罩效果实例代码
2016/06/24 Javascript
layui前段框架日期控件使用方法详解
2017/05/19 Javascript
Vue2.0 v-for filter列表过滤功能的实现
2018/09/07 Javascript
JavaScript函数式编程(Functional Programming)组合函数(Composition)用法分析
2019/05/22 Javascript
微信小程序Echarts图表组件使用方法详解
2019/06/25 Javascript
js 实现 list转换成tree的方法示例(数组到树)
2019/08/18 Javascript
vue中beforeRouteLeave实现页面回退不刷新的示例代码
2019/11/01 Javascript
Echarts实现多条折线可拖拽效果
2019/12/19 Javascript
利用aardio给python编写图形界面
2017/08/21 Python
django 2.0更新的10条注意事项总结
2018/01/05 Python
3个用于数据科学的顶级Python库
2018/09/29 Python
python将四元数变换为旋转矩阵的实例
2019/12/04 Python
Python利用多线程同步锁实现多窗口订票系统(推荐)
2019/12/22 Python
Python 模拟生成动态产生验证码图片的方法
2020/02/01 Python
pytorch之Resize()函数具体使用详解
2020/02/27 Python
python读取配置文件方式(ini、yaml、xml)
2020/04/09 Python
美国电视购物:QVC
2017/02/06 全球购物
英国工具中心:UK Tool Centre
2017/07/10 全球购物
FirstCry阿联酋儿童和婴儿产品网上购物:FirstCry.ae
2021/02/22 全球购物
档案检查欢迎词
2014/01/13 职场文书
党员公开承诺书范文
2014/03/25 职场文书
应届大专生求职信
2014/06/26 职场文书
励志演讲稿600字
2014/08/21 职场文书
2014年应急工作总结
2014/12/11 职场文书
供应商食品安全承诺书
2015/04/29 职场文书
工作服管理制度范本
2015/08/06 职场文书
JDBC连接的六步实例代码(与mysql连接)
2021/05/12 MySQL
Python游戏开发实例之graphics实现AI五子棋
2021/11/01 Python
MySQL串行化隔离级别(间隙锁实现)
2022/06/16 MySQL