# 前端工程自动化
# require.context (opens new window)
它是一个 webpack 的 api,通过执行 require.context 函数获取一个特定的上下文,主要用来实现自动化导入模块。在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个 api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用 import 导入模块。
# 异步组件加载
- 批量用:
require.context('locales', true, /\.js$/, 'lazy') - 单个组件:
import(/* webpackChunkName: "home" */ '@/xxxx') - webpack 把这个模块导出一个 js 文件,然后用到这个模块的时候,就动态构造 script 标签插入 DOM,再由浏览器去请求。
# 什么时候用
在 Vue 写的项目中,路由通过不同的功能划分成不同的模块,在 index.js 中一个个导入,但是如果项目变大了之后,每次手动 import 会显得代码很长,这里可以使用 require.context 函数遍历 modules 文件夹的所有文件一次性导入到 index.js 中。
// 一个个文件导入
import a from './modules/a'
import b from './modules/b'
import c from './modules/c'
import d from './modules/d'
import e from './modules/e'
import f from './modules/f'
import g from './modules/g'
import h from './modules/h'
// ....
// 再一个个解构
export default new Router({
routes: [
...a,
...b,
...c,
...d,
...e,
...f,
...g,
...h
// ...
]
})
# 如何使用
- 新建获取全路由的方法
/**
* 获取全路由
* @param {Array} context 数组
* @param {Object} ignore 字符
*/
export const getRoutes = (context, ignore) => {
const children = []
context.keys().forEach(key => {
if (key !== ignore) {
try {
let arr = context(key).default
if (arr && arr.length) {
children.push(...arr)
}
} catch (e) {
console.error(e)
}
}
})
return children
}
- 在 router/modules 下新建
index.js文件
import { getRoutes } from '_utils/utils'
/**
* @desc require.context函数三个参数
* @param directory {String} -读取文件的路径
* @param useSubdirectories {Boolean} -是否遍历文件的子目录
* @param regExp {RegExp} -匹配文件的正则
*/
export default getRoutes(require.context('./', false, /\.js$/), './index.js')
- 修改路由
index.js文件
import Router from 'vue-router'
import routes from './modules'
export default new Router({
mode: 'history',
base: '/vue',
routes
})
- 同理 store 自动加载改造如下
/**
* @desc 加载所有store文件
*/
const getModules = (context, ignore) => {
const modules = {}
context.keys().forEach(key => {
if (!ignore.includes(key)) {
modules[key.replace(/\.\/|\.js/g, '')] = context(key).default
}
})
return modules
}
export default getModules(require.context('./', false, /\.js$/), './index.js')
# 拓展 globEager
vite 脚手架下使用import.meta.globEager替换require.contextAPI
import { getRoutes } from '@/utils/common'
export default getRoutes(import.meta.globEager('./*.ts'), './index.ts')