详解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 相关文章推荐
java script编程起步(第三课)
Jan 10 Javascript
javascript对JSON数据排序的3个例子
Apr 12 Javascript
使用iojs的jsdom库实现同步系统时间
Apr 20 Javascript
js实现简洁的滑动门菜单(选项卡)效果代码
Sep 04 Javascript
Bootstrap页面布局基础知识全面解析
Jun 13 Javascript
BootstrapTable请求数据时设置超时(timeout)的方法
Jan 22 Javascript
JS实现DIV高度自适应窗口示例
Feb 16 Javascript
Bootstrap模态框案例解析
Mar 05 Javascript
jQuery实现模糊查询的方法分析
May 10 jQuery
快速解决vue在ios端下点击响应延时的问题
Aug 27 Javascript
vue服务端渲染操作简单入门实例分析
Aug 28 Javascript
vant picker+popup 自定义三级联动案例
Nov 04 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
WordPress迁移时一些常见问题的解决方法整理
2015/11/24 PHP
Yii2 中实现单点登录的方法
2018/03/09 PHP
php解决约瑟夫环算法实例分析
2019/09/30 PHP
laravel清除视图缓存的代码
2019/10/23 PHP
小议Function.apply()之二------利用Apply的参数数组化来提高 JavaScript程序性能
2006/11/30 Javascript
MC Dialog js弹出层 完美兼容多浏览器(5.6更新)
2010/05/06 Javascript
javascript提取URL的搜索字符串中的参数(自定义函数实现)
2013/01/22 Javascript
jQuery中json对象的复制方式介绍(数组及对象)
2013/06/08 Javascript
js输入框邮箱自动提示功能代码实现
2013/12/10 Javascript
javascript省市级联功能实现方法实例详解
2015/10/20 Javascript
jQuery实现放大镜效果实例代码
2016/03/17 Javascript
Ionic2调用本地SQlite实例
2017/04/22 Javascript
浅谈JS中的反柯里化( uncurrying)
2017/08/17 Javascript
Angularjs 1.3 中的$parse实例代码
2017/09/14 Javascript
vue 项目如何引入微信sdk接口的方法
2017/12/18 Javascript
Nodejs在局域网配置https访问的实现方法
2020/10/17 NodeJs
python错误处理详解
2014/09/28 Python
python subprocess 杀掉全部派生的子进程方法
2017/01/16 Python
AI人工智能 Python实现人机对话
2017/11/13 Python
http请求 request失败自动重新尝试代码示例
2018/01/25 Python
python 字典 按key值大小 倒序取值的实例
2018/07/06 Python
Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
2019/06/25 Python
python dataframe NaN处理方式
2019/12/26 Python
俄罗斯一家时尚女装商店:Charuel
2019/12/04 全球购物
关于赌博的检讨书
2014/01/08 职场文书
打架检讨书400字
2014/01/17 职场文书
科技之星事迹材料
2014/06/02 职场文书
明星员工获奖感言
2014/08/14 职场文书
解除聘用合同证明书范本
2014/09/11 职场文书
秋季运动会开幕词
2015/01/28 职场文书
灵魂歌王观后感
2015/06/17 职场文书
大学生活感想
2015/08/10 职场文书
防震减灾主题班会
2015/08/14 职场文书
导游词之沈阳植物园
2019/11/30 职场文书
Nginx location 和 proxy_pass路径配置问题小结
2021/09/04 Servers
Python安装及建立虚拟环境的完整步骤
2022/06/25 Servers