详解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 相关文章推荐
Visual Studio中的jQuery智能提示设置方法
Mar 27 Javascript
jquery的extend和fn.extend的使用说明
Jan 09 Javascript
基于jQuery的获取标签名的代码
Jul 16 Javascript
JS返回iframe中frameBorder属性值的方法
Apr 01 Javascript
JQUERY表单暂存功能插件分享
Feb 23 Javascript
详解JS正则replace的使用方法
Mar 06 Javascript
基于JS实现类似支付宝支付密码输入框
Sep 02 Javascript
jQuery实现动态给table赋值的方法示例
Jul 04 jQuery
vue编译打包本地查看index文件的方法
Feb 23 Javascript
妙用缓存调用链实现JS方法的重载
Apr 30 Javascript
Node.js中出现未捕获异常的处理方法
Jun 29 Javascript
vue cli4.0项目引入typescript的方法
Jul 17 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中使用与Perl兼容的正则表达式
2006/11/26 PHP
PHP 代码规范小结
2012/03/08 PHP
destoon安装出现Internal Server Error的解决方法
2014/06/21 PHP
ThinkPHP中RBAC类的四种用法分析
2014/11/24 PHP
thinkphp框架下404页面设置 仅三步
2016/05/14 PHP
js实现的网站首页随机公告随机公告
2007/03/14 Javascript
TimergliderJS 一个基于jQuery的时间轴插件
2011/12/07 Javascript
js鼠标滑过弹出层的定位IE6bug解决办法
2012/12/26 Javascript
使用js显示当前时间示例
2014/03/02 Javascript
文本域中换行符的替换示例
2014/03/04 Javascript
Jquery焦点与失去焦点示例应用
2014/06/10 Javascript
使用jQuery仿苹果官网焦点图特效
2014/12/23 Javascript
JS基于递归实现倒计时效果的方法
2016/11/26 Javascript
微信小程序 switch组件详解及简单实例
2017/01/10 Javascript
浅谈angular4生命周期钩子
2017/09/05 Javascript
vue+iview 实现可编辑表格的示例代码
2018/10/31 Javascript
vue中的mvvm模式讲解
2019/01/31 Javascript
详解微信小程序的不同函数调用的几种方法
2019/05/08 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
2019/05/10 Javascript
记录vue做微信自定义分享的一些问题
2019/09/12 Javascript
[15:57]教你分分钟做大人:斧王
2014/10/30 DOTA
pandas通过loc生成新的列方法
2018/11/28 Python
python操作文件的参数整理
2019/06/11 Python
简单瞅瞅Python vars()内置函数的实现
2019/09/27 Python
Flask之pipenv虚拟环境的实现
2019/11/26 Python
Django 返回json数据的实现示例
2020/03/05 Python
Python 给下载文件显示进度条和下载时间的实现
2020/04/02 Python
简单介绍HTML5中的文件导入
2015/05/08 HTML / CSS
Jeep牧马人、切诺基和自由人零配件:4 Wheel Drive Hardware
2017/07/02 全球购物
英国最大的化装舞会服装网站:Fancydress.com
2017/08/15 全球购物
2014年应届大学生自我评价
2014/01/09 职场文书
法人授权委托书范本
2014/04/04 职场文书
《三亚落日》教学反思
2014/04/26 职场文书
电气工程及其自动化专业求职信
2014/06/23 职场文书
不错的求职信范文
2014/07/20 职场文书
sqlserver2017共享功能目录路径不可改的解决方法
2021/04/16 SQL Server