详解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进度条插件 Progress Bar小问题解决
Jul 12 Javascript
ExtJS的拖拽效果示例
Dec 09 Javascript
jQuery 回车事件enter使用示例
Feb 18 Javascript
jQuery简单几行代码实现tab切换
Mar 10 Javascript
JS实现页面数据无限加载
Sep 13 Javascript
AngularJS入门教程之MVC架构实例分析
Nov 01 Javascript
Vue.js事件处理器与表单控件绑定详解
Mar 20 Javascript
React中jquery引用的实现方法
Sep 12 jQuery
jQuery实现可兼容IE6的淡入淡出效果告警提示功能示例
Sep 20 jQuery
vue实现滑动超出指定距离回顶部功能
Jul 31 Javascript
Nuxt页面级缓存的实现
Mar 09 Javascript
jquery插件实现搜索历史
Apr 24 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版)
2006/10/09 PHP
浅谈php中curl、fsockopen的应用
2016/12/10 PHP
PHP7实现和CryptoJS的AES加密方式互通示例【AES-128-ECB加密】
2019/06/08 PHP
Laravel框架控制器的request与response用法示例
2019/09/30 PHP
jQuery实现级联菜单效果(仿淘宝首页菜单动画)
2014/04/10 Javascript
javascript实现客户端兼容各浏览器创建csv并下载的方法
2015/03/23 Javascript
用svg制作富有动态的tooltip
2015/07/17 Javascript
动态更新highcharts数据的实现方法
2016/05/28 Javascript
用js写的一个路由(简单实例)
2016/09/24 Javascript
vue.js+Element实现表格里的增删改查
2017/01/18 Javascript
Bootstrap禁用响应式布局的实现方法
2017/03/09 Javascript
JavaScript实现计数器基础方法
2017/10/10 Javascript
vue中过滤器filter的讲解
2019/01/21 Javascript
jquery插件开发模式实例详解
2019/07/20 jQuery
详解Vue.js 作用域、slot用法(单个slot、具名slot)
2019/10/15 Javascript
Python中使用logging模块代替print(logging简明指南)
2014/07/09 Python
python实现删除文件与目录的方法
2014/11/10 Python
Python装饰器的执行过程实例分析
2018/06/04 Python
Python调用adb命令实现对多台设备同时进行reboot的方法
2018/10/15 Python
Python调用C++,通过Pybind11制作Python接口
2018/10/16 Python
pytorch三层全连接层实现手写字母识别方式
2020/01/14 Python
Tensorflow--取tensorf指定列的操作方式
2020/06/30 Python
python爬虫中的url下载器用法详解
2020/11/30 Python
HTML5 video进入全屏和退出全屏的实现方法
2020/07/28 HTML / CSS
瑞士国际航空官网:SWISS
2016/07/21 全球购物
英国第一豪华护肤品牌:Elemis
2017/10/12 全球购物
Smallable意大利家庭概念店:设计师童装及家居装饰
2018/01/08 全球购物
2014幼儿园教师师德师风演讲稿
2014/09/10 职场文书
会计人员演讲稿
2014/09/11 职场文书
销售员态度差检讨书
2014/10/26 职场文书
人力资源部岗位职责
2015/02/11 职场文书
2016年10月份红领巾广播稿
2015/12/21 职场文书
2016优秀青年志愿者事迹材料
2016/02/25 职场文书
股东合作协议书模板2篇
2019/11/05 职场文书
你真的了解PHP中的引用符号(&)吗
2021/05/12 PHP
delete in子查询不走索引问题分析
2022/07/07 MySQL