12.Vuex动态加载所有模块modules

426 阅读1分钟

1. require.context 

require.context(directory, useSubdirectories, regExp)
  1. directory: 要查找的文件路径
  2. useSubdirectories: 是否查找子目录
  3. regExp: 要匹配文件的正则

用法

require.context('./components/', true, /.js$/)

1.1 require.context返回一个方法webpackContext

require.context执行后,返回一个方法webpackContext,这个方法又返回一个__webpack_require__,这个__webpack_require__就相当于require或者import。同时webpackContext还有两个静态方法keys与resolve,一个id属性。

image.png

image.png

  1. keys: 返回匹配成功模块的名字组成的数组
  2. resolve: 接受一个参数request,request为test文件夹下面匹配文件的相对路径,返回这个匹配文件相对于整个工程的相对路径
  3. id: 执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载

2. 动态加载store模块require.context 

如果仅使用模块,可以使用 require.context 来动态地加载所有的模块。

// store.js
import Vue from 'vue'
import Vuex from 'vuex'

// 加载所有模块。
function loadModules() {
  const context = require.context("./modules", false, /([a-z_]+).js$/i)

  const modules = context
    .keys()
    .map((key) => ({ key, name: key.match(/([a-z_]+).js$/i)[1] }))
    .reduce(
      (modules, { key, name }) => ({
        ...modules,
        [name]: context(key).default
      }),
      {}
    )

  return { context, modules }
}

const { context, modules } = loadModules()

Vue.use(Vuex)

const store = new Vuex.Store({
  modules
})

image.png

image.png

// src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)
  // console.log('modulesFiles:',modulesFiles)
  // console.log('modulesFiles.keys():',modulesFiles.keys())
  
// 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)
   // console.log('modulePath:',modulePath)
  // console.log('moduleName:',moduleName)
  // console.log('modulesFiles(modulePath):',modulesFiles(modulePath))
  modules[moduleName] = value.default
  //console.log('modules:',modules);
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store

image.png