详解webpack import()动态加载模块踩坑
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')。果不其然,挂了。浏览器表示,没有鱼丸没有粗面,也不知道这个傻逼模块在哪里。
于是我查看了官方文档,发现有一个黄条提示。
emmm,看来问题出在这里了。
这个现象其实是与webpack import()的实现高度相关的。由于webpack需要将所有import()的模块都进行单独打包,所以在工程打包阶段,webpack会进行依赖收集。
此时,webpack会找到所有import()的调用,将传入的参数处理成一个正则,如:
import('./app'+path+'/util') => /^\.\/app.*\/util$/
也就是说,import参数中的所有变量,都会被替换为【.*】,而webpack就根据这个正则,查找所有符合条件的包,将其作为package进行打包。
因此,如果我们直接传入一个变量,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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- 详解webpack异步加载业务模块
- 教你怎么使用 webpack3 的 HMR 模块热加载
- 详解webpack2异步加载套路
- 详解vue项目优化之按需加载组件-使用webpack require.ensure
- webpack前端模块加载工具
- 详解AngularJS通过ocLazyLoad实现动态(懒)加载模块和依赖
- 详解webpack模块加载器兼打包工具
- webpack前端模块加载工具
- 【108】Vue-router 2.8.1 懒加载使用Webpack 3 的import() 语句出错的解决办法
- 详解webpack 入门总结和实践(按需异步加载,css单独打包,生成多个入口文件)
- react---react router4.0路由中如何异步动态加载组件,webpack使用require.ensure()生成异步chunk
- Javascript模块加载捆绑器Browserify Webpack和SystemJS用法
- AngularJs动态加载模块和依赖注入详解
- webpack 模块加载兼打包工具——入门或进阶
- Webpack 4.0.0 正式发布,模块加载打包工具
- webpack前端模块加载工具
- webpack异步加载业务模块
- AngularJs动态加载模块和依赖注入详解
- 浅谈Webpack 是如何加载模块的
- webpack里CommonJS的require与ES6 的module.exports加载模块有何不同