关于webpack require.context() 的那点事

先说

webpack里面有这么一招:使用require.context()方法来自动导入模块vue

官方文档有点深奥,老衲百度下拿了一段来直接使用,可是想看下它是如何运行的webpack

本篇这里不会有太深刻的研究,只是用一种解读方式更有助于理解它的原理web

老衲使用的是随便vue项目的vuex改造来作例子vuex

咱们这里只研究require.context()怎么回事,不是讲解vuex怎么改造。chrome

开始

先建这么个目录结构,里面2个模块:数组

模块里随便导出点东西,咱们就用简单的对象:bash

在store.js中,而后咱们抄了段代码是这样子的:函数

固然是先看输出结果,是这样子的:ui

这样,就成功读取了咱们2个文件内导出的模块对象 spa

研究

上面的代码可能有点玄乎,咱们来改造下,拆解成最土的代码以便理解,好比这样子:

require.context()运行后,返回的是一个函数,把rcfn打印出来:

能够点击它(使用chrome),进入这个函数内部,看到这么些东西:

下面的模块向外暴露出webpackContext方法

这个方法有一个参数,返回了使用__webpack_require__方法加载的模块

而且webpackContext还有一个keys属性,是一个方法,返回了上面map对象的key

也就是咱们上面例子调用时,modules目录下面的文件+路径名

因此很清楚了,代码中咱们使用const moduleKeys = rcfn.keys(),来获得文件名数组:

新建一个空数组,遍历上面那个获得的文件名+路径数组,带入最开始require.context()返回的方法rcfn

上面提到,这个返回的方法,其实内部就是返回引用__webpack_require__来加载模块

这样,咱们获得了modules数组,里面就是2个元素,每一个元素里面有咱们导出的默认模块

使用map过滤一下:

解散

总结 require.context() 用法就是 遍历目录下的文件名,再用文件名来加载文件中的模块。


改造

仍是发一下吧。。直接上代码

export default new Vuex.Store({    modules: {        ...(r => {             return r.keys().reduce((c, n) => {                 c[n.match(/(?<=\/).*?(?=\.js)/gi)]=r(n).default                return c            }, [])        })( require.context('./modules/', true, /\.js$/) )    }})复制代码

用一个当即执行函数,传入require.context()反回的方法

获取到文件名map并使用reduce遍历,按文件名做为key,取得模块,推入数组(这里不使用push,使用key值,居然也能够。。),并返回

最后是这么一个数组,用...展开便可


这里使用正则去掉不要的字符,那奇怪的正则语法叫正向前瞻正向后瞻,相关资料本身百度

相关文章
相关标签/搜索