详解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 12 Javascript
完美兼容各大浏览器的jQuery插件实现图片切换特效
Dec 12 Javascript
JS和css实现检测移动设备方向的变化并判断横竖屏幕
May 25 Javascript
浅谈window对象的scrollBy()方法
Jul 15 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
Aug 22 Javascript
深入剖析javascript中的exec与match方法
May 18 Javascript
jQuery实现打开页面渐现效果示例
Jul 27 Javascript
jquery精度计算代码 jquery指定精确小数位
Feb 06 Javascript
微信小程序拼接图片链接无底洞深入探究
Sep 03 Javascript
使用layer弹窗提交表单时判断表单是否输入为空的例子
Sep 26 Javascript
如何用vue-cli3脚手架搭建一个基于ts的基础脚手架的方法
Dec 12 Javascript
JavaScript或jQuery 获取option value值方法解析
May 12 jQuery
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 email邮箱正则
2008/10/08 PHP
用php实现的下载css文件中的图片的代码
2010/02/08 PHP
php fputcsv命令 写csv文件遇到的小问题(多维数组连接符)
2011/05/24 PHP
PHP随机字符串生成代码(包括大小写字母)
2013/06/24 PHP
PHP+MySQL修改记录的方法
2015/01/21 PHP
详解WordPress开发中用于获取分类及子页面的函数用法
2016/01/08 PHP
用javascript实现兼容IE7的类库 IE7_0_9.zip提供下载
2007/08/08 Javascript
让你的网站可编辑的实现js代码
2009/10/19 Javascript
jquery操作 iframe的方法
2014/12/03 Javascript
AngularJS表单编辑提交功能实例
2015/02/13 Javascript
jsMind通过鼠标拖拽的方式调整节点位置
2015/04/13 Javascript
JS模式之单例模式基本用法
2015/06/30 Javascript
深入理解jQuery事件绑定
2016/06/02 Javascript
JavaScript实现滑动导航栏效果
2017/08/30 Javascript
JavaScript实现二叉树的先序、中序及后序遍历方法详解
2017/10/26 Javascript
vue中v-model动态生成的实例详解
2017/10/27 Javascript
关于Vue在ie10下空白页的debug小结
2018/05/02 Javascript
使用webpack3.0配置webpack-dev-server教程
2018/05/29 Javascript
jQuery实现的页面弹幕效果【测试可用】
2018/08/17 jQuery
详解微信小程序缓存--缓存时效性
2019/05/02 Javascript
微信小程序实现拍照画布指定区域生成图片
2019/07/18 Javascript
Vue.js页面中有多个input搜索框如何实现防抖操作
2019/11/04 Javascript
Vue组件模板的几种书写形式(3种)
2020/02/19 Javascript
Python英文文本分词(无空格)模块wordninja的使用实例
2019/02/20 Python
我喜欢你 抖音表白程序python版
2019/04/07 Python
Mac安装python3的方法步骤
2019/08/09 Python
Python二元赋值实用技巧解析
2019/10/25 Python
pytorch .detach() .detach_() 和 .data用于切断反向传播的实现
2019/12/27 Python
Django用户身份验证完成示例代码
2020/04/03 Python
Python爬虫实例——爬取美团美食数据
2020/07/15 Python
Lookfantastic法国官网:英国知名美妆购物网站
2017/10/28 全球购物
英国独特礼物想法和个性化礼物网站:notonthehighstreet.com
2018/04/16 全球购物
程序员跳槽必看面试题总结
2013/06/28 面试题
舞蹈毕业生的自我评价
2014/03/05 职场文书
违纪开除通知书
2015/04/25 职场文书
Java实现经典游戏泡泡堂的示例代码
2022/04/04 Java/Android