详解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 Archive Network 集合
May 12 Javascript
建议大家看下JavaScript重要知识更新
Jul 08 Javascript
javascript各种复制代码收集
Sep 20 Javascript
prototype 中文参数乱码解决方案
Nov 09 Javascript
鼠标经过显示二级菜单js特效
Aug 13 Javascript
js this函数调用无需再次抓获id,name或标签名
Mar 03 Javascript
jQuery进行组件开发完整实例
Dec 15 Javascript
整理关于Bootstrap列表组的慕课笔记
Mar 29 Javascript
bootstrap精简教程_动力节点Java学院整理
Jul 14 Javascript
关于vue组件事件属性穿透详解
Oct 28 Javascript
微信小程序tabBar设置实例解析
Nov 14 Javascript
vue 使用post/get 下载导出文件操作
Aug 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
漂亮但不安全的CTB
2006/10/09 PHP
YII Framework框架教程之缓存用法详解
2016/03/14 PHP
PHP下 Mongodb 连接远程数据库的实例代码
2017/08/30 PHP
php分享朋友圈的实现代码
2019/02/18 PHP
jquery插件制作 自增长输入框实现代码
2012/08/17 jQuery
JS保留两位小数 四舍五入函数的小例子
2013/11/20 Javascript
js检测浏览器版本、核心、是否移动端示例
2014/04/24 Javascript
JavaScript实现网页对象拖放功能的方法
2015/04/15 Javascript
基于JS实现无缝滚动思路及代码分享
2016/06/07 Javascript
浅谈JQ中mouseover和mouseenter的区别
2016/09/13 Javascript
vue如何使用 Slot 分发内容实例详解
2017/09/05 Javascript
vue-router+vuex addRoutes实现路由动态加载及菜单动态加载
2017/09/28 Javascript
ajax前台后台跨域请求处理方式
2018/02/08 Javascript
JavaScript学习笔记之DOM基础操作实例小结
2019/01/09 Javascript
总结4个方面优化Vue项目
2019/02/11 Javascript
微信小程序中使用Async-await方法异步请求变为同步请求方法
2019/03/28 Javascript
vue2.0自定义指令示例代码详解
2019/04/25 Javascript
Python和Ruby中each循环引用变量问题(一个隐秘BUG?)
2014/06/04 Python
Python3实现发送QQ邮件功能(附件)
2020/12/23 Python
python实现音乐下载器
2018/04/15 Python
解决python3中的requests解析中文页面出现乱码问题
2019/04/19 Python
django写用户登录判定并跳转制定页面的实例
2019/08/21 Python
Python爬虫运用正则表达式的方法和优缺点
2019/08/25 Python
pygame实现五子棋游戏
2019/10/29 Python
Python实现报警信息实时发送至邮箱功能(实例代码)
2019/11/11 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
python实现企业微信定时发送文本消息的实例代码
2020/11/25 Python
HTML5制作酷炫音频播放器插件图文教程
2014/12/30 HTML / CSS
荟萃全球保健品:维他购
2018/05/09 全球购物
SOA的常见陷阱或者误解是什么
2014/10/05 面试题
食品厂厂长岗位职责
2014/01/30 职场文书
环保标语口号
2014/06/13 职场文书
观看信仰心得体会
2014/09/04 职场文书
Node实现搜索框进行模糊查询
2021/06/28 Javascript
python中redis包操作数据库的教程
2022/04/19 Python