详解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通过class来获取元素实现代码
Feb 20 Javascript
jquery异步跨域访问代码
Jun 28 Javascript
jQuery实现带渐显效果的人物多级关系图代码
Oct 16 Javascript
vue,angular,avalon这三种MVVM框架优缺点
Apr 27 Javascript
Web打印解决方案之证件套打的实现思路
Aug 29 Javascript
JavaScript获取服务器端时间的方法
Nov 29 Javascript
详解webpack进阶之loader篇
Aug 23 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
Sep 29 Javascript
实例讲解JS中pop使用方法
Jan 27 Javascript
详解小程序循环require之坑
Mar 08 Javascript
微信小程序之 catalog 切换实现解析
Sep 12 Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
Aug 25 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下连接mssql2005的代码
2011/01/17 PHP
PHP Cookie的使用教程详解
2013/06/03 PHP
php中\r \r\n \t的区别示例介绍
2014/02/08 PHP
基于PHP实现用户在线状态检测
2020/11/10 PHP
Prototype使用指南之array.js
2007/01/10 Javascript
JS 有名函数表达式全面解析
2010/03/19 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
2013/05/08 Javascript
jQuery产品间断向下滚动效果核心代码
2014/05/08 Javascript
javascript学习笔记(一)基础知识
2014/09/30 Javascript
JavaScript设计模式之建造者模式介绍
2014/12/28 Javascript
Javascript 完美运动框架(逐行分析代码,让你轻松了运动的原理)
2015/01/23 Javascript
AngularJS实现标签页的两种方式
2016/09/05 Javascript
JavaScript校验Number(4,1)格式的数字实例代码
2017/03/13 Javascript
微信小程序 商城开发(ecshop )简单实例
2017/04/07 Javascript
Vue项目组件化工程开发实践方案
2018/01/09 Javascript
浅谈vue中改elementUI默认样式引发的static与assets的区别
2018/02/03 Javascript
判断“命令按钮”是否被鼠标单击详解
2019/07/31 Javascript
使用vuex较为优雅的实现一个购物车功能的示例代码
2019/12/09 Javascript
python命令行参数sys.argv使用示例
2014/01/28 Python
基于Python的文件类型和字符串详解
2017/12/21 Python
pyspark.sql.DataFrame与pandas.DataFrame之间的相互转换实例
2018/08/02 Python
python+Splinter实现12306抢票功能
2018/09/25 Python
Python设计模式之建造者模式实例详解
2019/01/17 Python
详解Python 爬取13个旅游城市,告诉你五一大家最爱去哪玩?
2019/05/07 Python
Django组件content-type使用方法详解
2019/07/19 Python
python实现简单井字棋小游戏
2020/03/05 Python
HTML5在手机端实现视频全屏展示方法
2020/11/23 HTML / CSS
法国综合购物网站:RueDuCommerce
2016/09/12 全球购物
Superdry瑞典官网:英国日本街头风品牌
2017/05/17 全球购物
英国DIY汽车维修配件网站:DIY Car Service Parts
2019/08/30 全球购物
求职信的要素有哪些呢
2013/12/26 职场文书
先进个人事迹材料
2014/12/29 职场文书
​(迎国庆)作文之我爱我的祖国
2019/09/19 职场文书
python用tkinter开发的扫雷游戏
2021/06/01 Python
MySQL系列之十一 日志记录
2021/07/02 MySQL
全面盘点MySQL中的那些重要日志文件
2021/11/27 MySQL