前端读取文件夹中文件的方式以及使用技巧

前端读取文件夹中文件的方式以及使用技巧

写在前面

场景:现在的前端项目都是基于模块化来开发的。

问题:如何快捷、优雅的引入相同类型的多个文件呢?

例如:

  • vuex 的使用场景中按业务或者模块组件来创建多个对应的 module.js 文件;
  • vue-router 的使用场景中按页面 模块划分,创建多个路由文件;
  • 在自定义组件/指令的时候,创建了多个组件/指令文件;

如何快速的引入或者注册这些文件呢?像下面这样吗?

【以 vue-router 为例】

// 以 vue-router 为例
import HomeRouter from './modules/home.js'
import LoginRouter from './modules/login.js'
// ... 重复上面的

const asyncRouterMap = []

asyncRouterMap.push(HomeRouter)
asyncRouterMap.push(LoginRouter)
// ... 重复上面的

【以 vuex 为例】

import baseModule from './modules/base.js'
import settingModule from './modules/setting.js'
import userModule from './modules/user.js'
// ... 重复上面的

const store = createStore({
    
    
  modules: {
    
    
	base: baseModule,
	setting: settingModule,
	user: userModule
  }
})

这显然是不优雅的!

正文

认识 require.context

require.contextwebpack 中,用来创建自己的 context module 上下文(模块)。

webpack 会在构建的时候解析代码中的 require.context()

扫描二维码关注公众号,回复: 14952853 查看本文章

语法: require.context(directory, useSubdirectories, regExp)

require.context 函数接收三个参数:

  • 1、directory; 要搜索的文件夹目录
  • 2、useSubdirectories; 表示是否检索子文件夹
  • 3、regExp; 匹配文件的正则表达式

如果想引入一个文件夹下面的所有文件,或者引入能匹配一个正则表达式的所有文件,这个功能就会很有帮助。

【语法示例1】

const modulesFiles = require.context('./modules', true, /\.js$/)

【语法示例2】

const modulesFiles = require.context('./modules', false, /\.vue$/)

一个 context module 会导出一个(require)函数,此函数可以接收一个参数: request。 此导出函数有三个属性:resolve, keys, id

  • resolve 是一个函数,它返回 request 被解析后得到的模块 id
  • keys 也是一个函数,它返回一个数组,由所有可能被此 context module 处理的请求组成。
  • idcontext module 的模块 id。 它可能在你使用 module.hot.accept 时会用到。

【使用示例1】

const cache = {
    
    }
const modulesFiles = require.context('./modules', true, /\.js$/)
modulesFiles.keys().forEach((key) => {
    
    
  cache[key] = r(key)
})

【使用示例2】

const cache = {
    
    };

function importAll(r) {
    
    
  r.keys().forEach((key) => (cache[key] = r(key)));
}

importAll(require.context('../components/', true, /\.js$/));
// 在构建时(build-time),所有被 require 的模块都会被填充到 cache 对象中。

这一切都要得益于 Webpack 出色的表现和性能。

项目中的使用示例

【使用示例一、在 vuex 中的使用】
不管你 modules 中有多少个 js 文件

/**
 * 自动读取modules文件夹中的vuex模块
 * 不用手动引入和注入
 */
const modulesFiles = require.context('./modules', true, /\.js$/)

const modules = modulesFiles.keys().reduce((modules, modulePath) => {
    
    
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {
    
    })

/**
 * 这里getters是单独拿出来的,全局统一用一个,用做取值的便捷手段。【也是官方推荐的】
 * 你也可以直接使用 this.$store.state.[moduleName].[paramName] 来取值
 * (PS:至于state,mutations,actions就由每个modules文件夹里面的文件,自己实现)
 */
const getters = {
    
    
  // 用户信息
  allInfo: state => state.user.userInfo,
  // 用户名
  name: state => state.user.userInfo.name,
  // 头像
  avatar: state => state.user.userInfo.avatar,
  // 语言
  language: state => state.language.language,
  // add_routes 是动态遍历出来,添加上去的路由
  addRoutes: state => state.permission.addRoutes,
  // 用户的原始permissions数据
  permissions: state => state.user.permissions,
  // 用户的路由菜单权限(完整的)
  routers: state => state.permission.routes
}

export default new Vuex.Store({
    
    
  modules,
  getters
})

【使用示例二、在 vuex 中的使用(与使用示例一相似)】

import getters from './getters'
// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex module from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
    
    
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {
    
    })

export default createStore({
    
    
  modules,
  getters
})

【使用示例三、批量注册 mixins

// src/mixins/index.js
const modulesFiles = require.context('./modules', true, /\.js$/)
const mixinsModules = modulesFiles.keys().reduce((modules, modulePath) => {
    
    
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {
    
    })

export default mixinsModules
// 在组件中使用时
import mixinsModules from '@/mixins/index.js
...
mixins: [mixinsModules.userMixin, mixinsModules.appMixin]

【使用示例四、批量注册 vue-router

const asyncRoutes = []
/**
 * 如果系统页面模块比较多,也可以分模块写
 */
/**
 * 自动扫描 modules 里面的路由模块,路由模块请根据业务自行拆分
 * modules 里面只能存放动态路由(需要根据权限来选择的路由)
 * 插入到 asyncRoutes 中
 * 基础路由全部写到constantRoutes中
 */
const files = require.context('./modules', false, /\.js$/)
files.keys().forEach(key => {
    
    
  const file = files(key).default
  // 根据导出的内容判断是否数组,如果数组需使用扩展运算符
  if (Array.isArray(file)) {
    
    
    asyncRoutes.push(...file)
  } else {
    
    
    asyncRoutes.push(file)
  }
})

—————————— 【正文完】——————————

前端学习交流群,想进来面基的,可以加群: 832485817685486827
React学习交流 Vue学习交流

写在最后: 约定优于配置 —— 软件开发的简约原则

——————————【完】——————————

我的:
个人网站: https://neveryu.github.io/neveryu/
Github: https://github.com/Neveryu
新浪微博: https://weibo.com/Neveryu
微信: miracle421354532

更多学习资源请关注我的新浪微博…好吗

猜你喜欢

转载自blog.csdn.net/csdn_yudong/article/details/125069996