require['context'] 与 require.context——下
import lodash from 'lodash'
import { clientType, decorType } from '@/utils/decor-types'
export function getModules() {
let modulesObj = {}
let requireModules
if (clientType === 'pc') {
requireModules = require['context']('@/components/decor/pc', true, /[A-Za-z]\w+\.(vue|js)$/)
} else {
requireModules = require['context']('@/components/decor/mobile', true, /[A-Za-z]\w+\.(vue|js)$/)
}
const requireModulesKeys = requireModules.keys()
// 遍历所有引入的文件中的index.js
// 将index.js中的配置装入modulesObj中
// 就相当于查找到了所有的装修模块
requireModulesKeys.forEach(fileName => {
if (fileName.indexOf('index.js') === -1) return
const moduleConfig = requireModules(fileName).default
const name = lodash.kebabCase(moduleConfig.name)
// 过滤一下装修类型
const { decor_type } = moduleConfig
if (decor_type !== undefined && (!decor_type.split(',').includes(decorType))) return
modulesObj[name] = moduleConfig
})
// 遍历modulesObj,也就是遍历所有模块
// 再根据模块名称name,过滤所有文件名
// 如果有模块名+Setting.vue的文件,将has_setting设为true,表示有Setting组件
Object.keys(modulesObj).forEach(key => {
let setting_name = lodash.camelCase(`${key}-setting`)
setting_name = lodash.upperFirst(setting_name) + '.vue'
const index = requireModulesKeys.findIndex(fileName => fileName.indexOf(setting_name) !== -1)
if (index !== -1) {
modulesObj[key]['has_setting'] = true
}
})
// 遍历modulesObj,把模块放入Modules数组中
// 顺便按照index.js中的sort字段排个序
const Modules = []
Object.keys(modulesObj).forEach(key => {
Modules.push(modulesObj[key])
Modules.sort((a, b) => a.sort - b.sort)
})
return Modules
}
结论先说:
- requireModules 不是“数据对象”,也不是 ES6 的 import 方法。
- 它是 Webpack 的 require.context 返回的“上下文 require 函数”——一个既能被调用又带有属性的方法对象。
为什么能“像函数那样调用”:
- require.context(directory, useSubdirectories, regExp) 会返回一个函数,这个函数用来按 key 动态加载匹配到的模块。
- 这个函数本身还挂了几个属性/方法:keys()、resolve()、id。
- 在 JavaScript 里,函数本身就是对象,可以同时“可调用”并拥有属性,这是正常的。
结合你的代码位置
- 在
中: - requireModules = require'context' 得到的是“上下文 require 函数”。
- requireModules(fileName) 就是“动态导入这个 fileName 对应的模块”。
- .default 的原因:被导入的 index.js 或 .vue 使用了 ES Module 的 export default 导出,因此要取 default 才是默认导出。如果某模块是用 module.exports 导出的,则不需要 .default。
你可以这样理解返回值形态
- typeof requireModules === 'function' 为 true;
- requireModules.keys() 会给出可用的 fileName 列表(如 './Foo/index.js');
- requireModules(fileName) 返回模块的导出对象,经常需要 .default 取默认导出。
如果想写得更“健壮”一点(兼容两种导出风格),可以这样处理返回值:
- const mod = requireModules(fileName);
- const moduleConfig = mod.default || mod;
这样就不管模块是 export default 还是 module.exports 都能拿到正确的配置对象。
本文来自博客园,作者:jialiangzai,转载请注明原文链接:https://www.cnblogs.com/zsnhweb/p/19059185

浙公网安备 33010602011771号