详解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调用wcf并展示出数据的方法
Jul 07 Javascript
使用jQuery快速解决input中placeholder值在ie中无法支持的问题
Jan 02 Javascript
jquery.validate使用时遇到的问题
May 25 Javascript
JavaScript取得WEB安全颜色列表的方法
Jul 14 Javascript
jquery实现可点击伸缩与展开的菜单效果代码
Aug 31 Javascript
Bootstrap每天必学之面板
Nov 30 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
Feb 29 Javascript
jQuery Mobile动态刷新页面样式的实现方法
May 28 Javascript
js获取form表单所有数据的简单方法
Aug 18 Javascript
Vue侧滑菜单组件——DrawerLayout
Dec 18 Javascript
vue.js删除列表中的一行
Jun 30 Javascript
jQuery实现高度灵活的表单验证功能示例【无UI】
Apr 30 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实现选择排序的解决方法
2013/05/04 PHP
php判断电脑访问、手机访问的例子
2014/05/10 PHP
php 删除cookie方法详解
2014/12/01 PHP
PHP解密Unicode及Escape加密字符串
2015/05/17 PHP
php进程daemon化的正确实现方法
2018/09/06 PHP
JavaScript入门教程(11) js事件处理
2009/01/31 Javascript
Javascript 日期对象Date扩展方法
2009/05/30 Javascript
jquery创建一个ajax关键词数据搜索实现思路
2013/02/26 Javascript
jQuery的live()方法对hover事件的处理示例
2014/02/27 Javascript
JS实现OCX控件的事件响应示例
2014/09/17 Javascript
JavaScript中Cookies的相关使用教程
2015/06/04 Javascript
JavaScript观察者模式(经典)
2015/12/09 Javascript
详解maxlength属性在textarea里奇怪的表现
2015/12/27 Javascript
浅谈JS原型对象和原型链
2016/03/02 Javascript
jquery 多个radio的click事件实例
2016/12/03 Javascript
老生常谈js中0到底是 true 还是 false
2017/03/08 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
2020/06/29 Javascript
Angular 2父子组件数据传递之@Input和@Output详解 (上)
2017/07/05 Javascript
浅谈Node模块系统及其模式
2017/11/17 Javascript
Vue.js中的高级面试题及答案
2020/01/13 Javascript
javascript canvas检测小球碰撞
2020/04/17 Javascript
vue基础知识--axios合并请求和slot
2020/06/04 Javascript
python爬虫入门教程--优雅的HTTP库requests(二)
2017/05/25 Python
Python的mysql数据库的更新如何实现
2017/07/31 Python
python实现对输入的密文加密
2019/03/20 Python
Django 路由控制的实现
2019/07/17 Python
python线程的几种创建方式详解
2019/08/29 Python
Python安装依赖(包)模块方法详解
2020/02/14 Python
python 制作本地应用搜索工具
2021/02/27 Python
C#的几个面试问题
2016/05/22 面试题
大学生就业自我鉴定
2013/10/26 职场文书
2014年商场超市庆元旦活动方案
2014/02/14 职场文书
美术教师个人工作总结
2015/02/06 职场文书
老公婚前保证书
2015/02/28 职场文书
react 项目中引入图片的几种方式
2021/06/02 Javascript
Python制作表白爱心合集
2022/01/22 Python