LeoWangJ / blog

紀錄學習文章
1 stars 0 forks source link

modules自動導入(require.context) #26

Open LeoWangJ opened 4 years ago

LeoWangJ commented 4 years ago

modules自動導入

一般我們在導入vuex的module時是使用import的方式一個一個去手動導入,但當每次新增一個module我們就必須記得去import,對於工程的角度來說能夠自動導入的話是最方便的,也不會忘記去導入。

手動添加module:

//moduleA.js
const moduleA = {
  state: { ... },
  mutations: { ... },
  actions: { ... },
  getters: { ... }
}

//moduleB.js
const moduleB = {
  state: { ... },
  mutations: { ... },
  actions: { ... }
}

// index.js
import moduleA from './moduleA'
import moduleB from './moduleB'

const store = new Vuex.Store({
  modules: {
    a: moduleA,
    b: moduleB
  }
})

require.context

所幸webpack中這個方法能夠讓我們自動導入檔案

require.context接受三個參數

  1. directory(string) - 要搜索的目錄
  2. useSubdirectories(boolean) - 是否要搜索子目錄
  3. regExp - 匹配文件的正則

usage:

//將遍歷當前目錄下的modules文件夾下的所有js檔案,包含子目錄
const modulesFiles = require.context('./modules', true, /\.js$/)

將modulesFiles打印出來後會發現requrie.context返回的是一個函數,這函數可以接受一個參數request且該函數包含了三個屬性resolve、keys、id,而此地方只會用到keys。

  1. keys - 返回匹配成功的模組名稱所組成的陣列
// index.js
const modulesFiles = require.context('./modules', true, /\.js$/)

// 將匹配成功的模組名稱陣列組合成我們想要的物件
// modulesFiles.keys() =>  ["./moduleA.js","./moduleB.js"]
const API = modulesFiles.keys().reduce((modules, modulePath) => {
  // 將模組路徑名稱正則成想要的名稱
  // ex: ./moduleA.js => moduleA
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  // 取得模組資料
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})
export default API

此時index.js 格式將會是

{
  moduleA:{
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
  },
  moduleB:{
    state: { ... },
    mutations: { ... },
    actions: { ... },
    getters: { ... }
  }
}

參考: