Automatic import module: require.context

Posted by Daniel Mott on Sat, 06 Nov 2021 14:28:24 +0100

When importing components and modules, the directory format is almost the same. Can you import all of them with one click? require.context Can help us achieve this function. Webpack is required (or Vue CLI 3 + that uses webpack internally)

Traditional import, if there are many files, it will be very troublesome, and each additional file in the later stage needs to be imported again

import moduleA from './modules/moduleA.vue'
import moduleB from './modules/moduleB.vue'
import moduleC from './modules/moduleC.vue'


export default {
  components: {
    moduleA,
    moduleB,
    moduleC
  }
}

Next, the article will introduce the use of require.context to automatically import the module for energy supply and liberate our hands.

First, let's introduce the require.context~

What is require.context

A webpack api obtains a specific context by executing the require.context function, which is mainly used to realize the automatic import module. In the front-end project, if you encounter the introduction of many modules from a folder, you can use this api. It will traverse the specified files in the folder and then import automatically, so that you do not need to explicitly call the import module every time

require.context method

The require.context function accepts three parameters

  • directory{String} - directory to search

  • useSubdirectories {Boolean} - do you also search its subdirectories

  • regExp {RegExp} - regular expression matching file

The syntax is as follows:

require.context(
  directory,
  (useSubdirectories = true),
  (regExp = /^\.\/.*$/),
  (mode = 'sync')
);

Borrow the example of webpack official website

require.context("./test", false, /\.test\.js$/);
// Traverse all files ending in '. test.js' in the test folder of the current directory, not subdirectories
require.context("../", true, /\.stories\.js$/);
//  Traverse all files ending in '. stories.js' in the current directory, and traverse subdirectories

Note: the parameter passed to require.context must be literal

Return of the require.context method

The require.context function returns a require function after execution. This function accepts a parameter: request

  • Xiaobian understands the use of the require function. For example, pass in the relative path of the matching file under the test folder to get the returned esmodule
  • Note: the test folder here refers to the first parameter value of the require.context function. Test is passed in here, so the relative path of the matching file under the test folder is passed in

This function has 3 properties

  • resolve {Function}

    • Official: accept a parameter request, which returns the module id obtained after the request is parsed
    • Xiaobian understanding: pass in the relative path of the matching file under the test folder and return the relative path of the matching file relative to the whole project
  • keys {Function}

    • Official: it returns an array consisting of all requests that may be processed by this context module.
    • Xiaobian understanding: return an array composed of the names of successful matching modules
  • id {String}

    • Official: it is the module id of context module. It may be used when you use module.hot.accept

View the property return value in combination with the project output

Only some codes are posted here. Specific engineering examples are shown below:

// 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 context = require.context('./modules', true, /\.js$/)
console.log('----------- context ---------')
console.log(context)
console.log('----------- contex.id ---------')
console.log(context.id)
console.log('----------- context.resolve---------')
console.log(context.resolve)
console.log('----------- context.resolve(./moduleA.js) ---------------')
console.log(context.resolve('./moduleA.js'))
console.log('----------- context.keys() ---------')
console.log(context.keys())

const modules = context.keys().reduce((modules, modulePath) => {
  // set './moduleA.js' => 'moduleA'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  console.log(`----------- context(${modulePath}) ------------`)
  const value = context(modulePath)
  console.log(value)
  modules[moduleName] = value.default
  return modules
}, {})

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

export default store

View console output:

Engineering example

Automated import component

catalogue

Core code

// App.vue
<template>
  <div id="app">
    <my-header></my-header>
    <my-main></my-main>
    <my-footer></my-footer>
  </div>
</template>

<script>
// critical code
const modulesFiles = require.context('./components', true, /\.vue$/)
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './myHeader.js' => 'myHeader'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})
export default {
  name: 'App',
  // critical code
  components: modules
}
</script>

Automatic import vuex module

catalogue

Core code

// store/modules/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 context = require.context('./modules', true, /\.js$/)

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

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

export default store

Project code

Here is the complete code of the automatic import module. You are welcome to fork and star. If you have any questions, you can ask issue

import-modules-auto

last

If you have any mistakes about the above, I hope you can point out more

Reference link

Use require.context to realize front-end engineering automation

webpack official website

Topics: Javascript