详解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 相关文章推荐
javascript数组组合成字符串的脚本
Jan 06 Javascript
javascript cookie解码函数(兼容ff)
Mar 17 Javascript
JavaScript/jQuery 表单美化插件小结
Feb 14 Javascript
jQuery旋转插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
Jan 16 Javascript
Mac中安装nvm的教程分享
Dec 11 Javascript
JS实现数组简单去重及数组根据对象中的元素去重操作示例
Jan 05 Javascript
Angular4学习笔记router的简单使用
Mar 30 Javascript
vue中动态select的使用方法示例
Oct 28 Javascript
小程序新版订阅消息模板消息
Dec 31 Javascript
前端性能优化建议
Sep 17 Javascript
vue 数字翻牌器动态加载数据
Apr 20 Vue.js
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
vs中通过剪切板循环来循环粘贴不同内容
2011/04/30 PHP
PHP模块memcached使用指南
2014/12/08 PHP
PHP实现的网站目录扫描索引工具
2016/09/08 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
PHP自动识别当前使用移动终端
2018/05/21 PHP
JS构建页面的DOM节点结构的实现代码
2011/12/09 Javascript
js FLASH幻灯片字符串中有连接符&的处理方法
2012/03/01 Javascript
基于jquery实现无限级树形菜单
2016/03/22 Javascript
JS碰撞运动实现方法详解
2016/12/15 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
2017/03/13 Javascript
angularJs中datatable实现代码
2017/06/03 Javascript
详解vue-cli中配置sass
2017/06/21 Javascript
Vue组件化通讯的实例代码
2017/06/23 Javascript
angular4实现tab栏切换的方法示例
2017/10/21 Javascript
js实现复制功能(多种方法集合)
2018/01/06 Javascript
微信小程序switch组件使用详解
2018/01/31 Javascript
vue-router 实现导航守卫(路由卫士)的实例代码
2018/09/02 Javascript
支付宝小程序自定义弹窗dialog插件的实现代码
2018/11/30 Javascript
浏览器事件循环与vue nextTicket的实现
2019/04/16 Javascript
wxpython中利用线程防止假死的实现方法
2014/08/11 Python
Python基于identicon库创建类似Github上用的头像功能
2017/09/25 Python
Python3利用Dlib19.7实现摄像头人脸识别的方法
2018/05/11 Python
Python异步编程之协程任务的调度操作实例分析
2020/02/01 Python
python 实现性别识别
2020/11/21 Python
Python中Qslider控件实操详解
2021/02/20 Python
采购经理岗位职责
2014/02/16 职场文书
2014党员民主评议个人总结
2014/09/10 职场文书
一年级班主任工作总结2014
2014/11/08 职场文书
2016年元旦主持词
2015/07/06 职场文书
中秋晚会致辞
2015/07/31 职场文书
“学党章、守党纪、讲党规”学习心得体会
2016/01/14 职场文书
2016年质量月活动总结报告
2016/04/05 职场文书
抖音短视频(douyin)去水印工具的实现代码
2021/03/30 Javascript
vue.js Router中嵌套路由的实用示例
2021/06/27 Vue.js
MySQL 十大常用字符串函数详解
2021/06/30 MySQL
MySQL中一条SQL查询语句是如何执行的
2022/04/08 MySQL