详解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 相关文章推荐
js 如何实现对数据库的增删改查
Nov 23 Javascript
在Javascript中 声明时用"var"与不用"var"的区别
Apr 15 Javascript
JS 新增Cookie 取cookie值 删除cookie 举例详解
Oct 10 Javascript
推荐9款炫酷的基于jquery的页面特效
Dec 07 Javascript
AngularJS基础学习笔记之简单介绍
May 10 Javascript
JavaScript中join()方法的使用简介
Jun 09 Javascript
javascript单页面手势滑屏切换原理详解
Mar 21 Javascript
基于javascript实现句子翻牌网页版小游戏
Mar 23 Javascript
jQuery移除或禁用html元素点击事件常用方法小结
Feb 10 Javascript
如何让node运行es6模块文件及其原理详解
Dec 11 Javascript
小程序实现按下录音松开识别语音
Nov 22 Javascript
js实现移动端图片滑块验证功能
Sep 29 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多线程异步请求的3种方法
2014/01/17 PHP
Sublime里直接运行PHP配置方法
2014/11/28 PHP
PHP使用array_fill定义多维数组的方法
2015/03/18 PHP
php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
2015/10/20 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
php curl上传、下载、https登陆实现代码
2017/07/23 PHP
php基于自定义函数记录log日志方法
2017/07/21 PHP
php服务器的系统详解
2019/10/12 PHP
laravel5.1 ajax post 传值_token示例
2019/10/24 PHP
js jq 单击和双击区分示例介绍
2013/11/05 Javascript
jQuery新的事件绑定机制on()示例应用
2014/07/18 Javascript
AngularJS实现表单手动验证和表单自动验证
2015/12/09 Javascript
微信小程序开发探究
2016/12/27 Javascript
jQuery实现联动下拉列表查询框
2017/01/04 Javascript
详解angular笔记路由之angular-router
2017/09/12 Javascript
SVG动画vivus.js库使用小结(实例代码)
2017/09/14 Javascript
vue 使用ref 让父组件调用子组件的方法
2018/02/08 Javascript
一文搞懂ES6中的Map和Set
2019/05/20 Javascript
JS秒杀倒计时功能完整实例【使用jQuery3.1.1】
2019/09/03 jQuery
vue el-upload上传文件的示例代码
2020/12/21 Vue.js
Python天气预报采集器实现代码(网页爬虫)
2012/10/07 Python
通过Python 获取Android设备信息的轻量级框架
2017/12/18 Python
python利用requests库进行接口测试的方法详解
2018/07/06 Python
对python文件读写的缓冲行为详解
2019/02/13 Python
python面向对象实现名片管理系统文件版
2019/04/26 Python
基于python二叉树的构造和打印例子
2019/08/09 Python
Python使用Turtle模块绘制国旗的方法示例
2021/02/28 Python
美国机场停车位预订:About Airport Parking
2018/03/26 全球购物
求职简历自荐信范文
2013/10/21 职场文书
程序员岗位职责
2013/11/11 职场文书
中医专业应届生求职信
2013/11/17 职场文书
工程管理专业个人求职信范文
2013/12/07 职场文书
网上开商店的创业计划书
2014/01/19 职场文书
机关单位2016年创先争优活动总结
2016/04/05 职场文书
JavaScript与JQuery框架基础入门教程
2021/07/15 Javascript
SONY600GR,国产收音机厂商永远的痛
2022/04/05 无线电