require.context() ——实现 vue 模块的自动导入

情景介绍

当项目逐渐庞大的时候,就有可能出现在一个文件中插入许多条导入语句。

import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';

import loginModule from './modules/login-module';
import userCenter from './modules/user-center';
import solution from './modules/solution';
import partner from './modules/partner';

如上,因为项目将 vue 路由按模块拆分成四个部分,所以 vue-router 配置文件需要对它们进行导入。如果拆分的模块越多,那就需要插入更多的导入语句。这样就会造成不便。

如果能实现模块的自动化导入,就可以解决这个问题。

模块的自动化导入:

模块的自动化导入就是在项目运行的时候自动到指定的目录去读取加载相应的模块,而不用人为的加以干扰设定。

(这里所说的模块特指通过 ES6 的 exportexport default或CommonJS 的 exportsmodule.exports 导出的JS文件)

require.context()

自动化的难点在于如何才能让编译器去自动访问读取模块文件。刚好require.context()就可以实现这部分功能。

require.context()webpack提供的一个方法,用于查找指定文件夹下的指定类型文件。

用法如下:

let modules = require.context(directory, useSubdirectories, regExp);

其接收三个参数:

参数描述类型
directory要查找的目录的路径string
useSubdirectories是否查找子目录boolean
regExp要匹配文件的正则表达式

require.context()的返回值一个函数webpackContext。该函数相当于 require ,接收一个路径字符串参数。该路径参数只能是 require.context 查找到的路径;

// 查找当前目录下的 modules 目录中的全部 js 文件
const webpackContext = require.context('./modules', true, /\.js/)// 查找到的第一个模块路径
let modulePath = webpackContext.keys()[0];

webpackContext(modulePath);	// require.context查找到的路径,加载成功
webpackContext('./test.js');	// 非 require.context 查找到的路径,加载失败

此外webpackContext还有两个静态方法 keys 和 resolve以及一个属性 id:

属性/方法描述类型
keys返回成功获取到的模块组成的数组function
resolve接收参数为匹配成功的模块路径,即keys中存储的值;其返回匹配文件相对于整个项目的相对路径function
id上下文模块的模块IDstring

借助require.context()实现vue路由子模块自动化导入

假设,子模块的路由配置文件都放在/router/modules下:

│?? ├── router                              vue-router
│?? │?? ├── modules                         vue-router 模块分离
│?? │?? └── index.js

在 index.js 添加如下代码:

// router/index.js

import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  }
];

// 查找 /router/modules 下的全部js文件
let webpackContext = require.context('./modules', true, /\.js/);

// 遍历查询结果,将查询到的文件加载后插入数组modules
let moudulesRoutes = webpackContext.keys().map((item => {
  // 逐一加载模块
  let route = webpackContext(item);
  
  return route;
}))// 将加载到的路由合并到 routes 中
moudulesRoutes.forEach(item => {
  routes.push(...item);
});

const router = new VueRouter({
  routes
});

export default router;

通过上面的代码,就可以实现路由子模块的自动化导入了。

其实上面的代码还可以优化,可以将自动化模块加载部分提取出来,以便于其他地方使用。

优化如下:

// automoted-import-modules.js
/**
 * 自动化批量导入模块
 *
 * 本函数需要配合 webpage 函数 require.context 来使用。
 * @param {Function} context require.context()返回的结果;
 * @returns {Array} 查找到的模块加载后,存入一个数组抛出
 */
function automatedImport(context) {
  return context.keys().map(item => {
    var value = context(item);

    return value.default || value;
  });
}

export default automatedImport;

这里需要注意一点,require.context() 不能放在函数中,放在函数中webpak将无法解析。

然后,如下调用:

// router/index.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
import automatedImport from '@/util/automoted-import-modules';

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  }
];

// 自动加载项目里全部模块的路由文件
const moudulesRoutes = automatedImport(require.context('./modules', true, /\.js/));

// 将加载到的路由合并到 routes 中
moudulesRoutes.forEach(item => {
  routes.push(...item);
});

const router = new VueRouter({
  routes
});

export default router;

结语

以上就是 vue 模块自动化导入的实现方法了。其实,该方法不仅仅局限于 Vue,因为 require.contextwebpack提供的方法,所以凡是基于webpack的项目都可以这样实现模块化自动导入。

参考文章

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue 3中,使用require.context会报错。这是因为在Vue 3中,已经不再支持使用require.context这个方法来进行模块自动导入了。这个方法在Vue 3的vite ts框架中使用会导致错误。为了解决这个问题,可以使用import.meta.globEager来替代require.context方法。具体的解决方案是使用import.meta.globEager("../../assets/authentication/*.png")来导入模块。这样可以避免报错并成功导入所需的模块。需要注意的是,这个方法可能在不同的环境中有所差异,所以需要根据具体情况来选择合适的导入方式。在Vue 2中,可以使用require.context方法来实现类似的功能,具体的使用方法是先引入path和files模块,然后使用files.keys()方法获取模块的键列表,再根据键列表来动态导入模块。但是在Vue 3中,需要使用import.meta.globEager方法来达到相同的效果。需要注意的是,在Vue 3中,模块导入方式有所改变,所以需要根据Vue 3的具体要求来修改代码。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [vue3+vite+ts使用require.context](https://blog.csdn.net/qq_40864647/article/details/125678833)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [vue3中require报错 require is not defined](https://blog.csdn.net/lys20000913/article/details/122959885)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值