详解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 相关文章推荐
JQuery SELECT单选模拟jQuery.select.js
Nov 12 Javascript
在JavaScript中获取请求的URL参数
Dec 22 Javascript
关于捕获用户何时点击window.onbeforeunload的取消事件
Mar 06 Javascript
jQuery动态改变图片显示大小(修改版)的实现思路及代码
Dec 24 Javascript
理运用命名空间让js不产生冲突避免全局变量的泛滥
Jun 15 Javascript
JavaScript输出当前时间Unix时间戳的方法
Apr 06 Javascript
TypeError document.getElementById(...) is null错误原因
May 18 Javascript
JQuery实现鼠标滚轮滑动到页面节点
Jul 28 Javascript
使用JavaScript触发过渡效果的方法
Jan 19 Javascript
简单的三步vuex入门
May 20 Javascript
Vue使用NProgress进度条的方法
Sep 21 Javascript
js实现简易计算器功能
Oct 18 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木马攻击防御之道
2008/03/24 PHP
Ajax PHP简单入门教程代码
2008/04/25 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
Redis在Laravel项目中的应用实例详解
2017/08/11 PHP
PHP中in_array的隐式转换的解决方法
2018/03/06 PHP
javascript 静态对象和构造函数的使用和公私问题
2010/03/02 Javascript
非阻塞动态加载javascript广告实现代码
2010/11/17 Javascript
仅IE不支持setTimeout/setInterval函数的第三个以上参数
2011/05/25 Javascript
DOM2非标准但却支持很好的几个属性小结
2012/01/21 Javascript
js字符串完全替换函数分享
2014/12/03 Javascript
Js和JQuery获取鼠标指针坐标的实现代码分享
2015/05/25 Javascript
AngularJS入门教程之MVC架构实例分析
2016/11/01 Javascript
Angular使用过滤器uppercase/lowercase实现字母大小写转换功能示例
2018/03/27 Javascript
父组件中vuex方法更新state子组件不能及时更新并渲染的完美解决方法
2018/04/25 Javascript
layui-table表复选框勾选的所有行数据获取的例子
2019/09/13 Javascript
javascript实现左右缓动动画函数
2020/11/25 Javascript
vue中如何自定义右键菜单详解
2020/12/08 Vue.js
[01:33:14]LGD vs VP Supermajor 败者组决赛 BO3 第二场 6.10
2018/07/04 DOTA
Python查看多台服务器进程的脚本分享
2014/06/11 Python
python简单判断序列是否为空的方法
2015/06/30 Python
Python 中pandas.read_excel详细介绍
2017/06/23 Python
python+pyqt实现12306图片验证效果
2017/10/25 Python
Django项目中包含多个应用时对url的配置方法
2018/05/30 Python
对tensorflow 的模型保存和调用实例讲解
2018/07/28 Python
Selenium定时刷新网页的实现代码
2018/10/31 Python
深入理解Python异常处理的哲学
2019/02/01 Python
Python 如何在字符串中插入变量
2020/08/01 Python
CSS3盒子模型详解
2013/04/24 HTML / CSS
世界第一曲奇连锁店:Mrs. Fields Cookies
2017/02/04 全球购物
高品质和独特的产品世界:Creations and Collections
2018/01/07 全球购物
财务工作者先进事迹材料
2014/01/17 职场文书
12月红领巾广播稿
2014/02/13 职场文书
青春寄语大全
2014/04/09 职场文书
护士节活动总结
2014/08/29 职场文书
关于公司年会的开幕词
2016/03/04 职场文书
动画电影《擅长捉弄人的高木同学》6月10日上映!
2022/03/20 日漫