Use node to implement webpack-like require.context() function

Use node to implement webpack-like require.context() function

Introduction: I'm writing a nuxt project recently. Because it is server-side rendering, a large number of internationalized files need to be loaded. It takes too much effort to import one by one, so I want to automatically import it. The first thing that comes to mind is the require.context() function of webpack, but server-side rendering Can't use it. So I wrote a file loader with node.

File Directory

.
├── autoLoadFile.js
└── langs
    ├── app
    │   ├── en.js
    │   └── zh.js
    ├── en.js
    └── zh.js

langs / en.js

// langs/app/en.js内容和这一样,加了app前缀
const en = {
    
    
  lang: 'en'
}

module.exports = en

along / zh.js

// langs/app/en.js内容和这一样,加了app前缀
const zh = {
    
    
  lang: '中文''
}

module.exports = zh

The core implements autoLoadFile.js

#!/usr/bin/env node
const path = require('path')
const fs = require('fs')
const getPathInfo = p => path.parse(p)

/**
 * @description // 递归读取文件,类似于webpack的require.context()
 * @time 2020-9-12
 *
 * @param {String} directory 文件目录
 * @param {Boolean} useSubdirectories 是否查询子目录,默认false
 * @param {array} extList 查询文件后缀,默认 ['.js']
 *
 */
function autoLoadFile(directory, useSubdirectories = false, extList = ['.js']) {
    
    
  const filesList = []
  // 递归读取文件
  function readFileList(directory, useSubdirectories, extList) {
    
    
    const files = fs.readdirSync(directory)
    files.forEach(item => {
    
    
      const fullPath = path.join(directory, item)
      const stat = fs.statSync(fullPath)
      if (stat.isDirectory() && useSubdirectories) {
    
    
        readFileList(path.join(directory, item), useSubdirectories, extList)
      } else {
    
    
        const info = getPathInfo(fullPath)
        extList.includes(info.ext) && filesList.push(fullPath)
      }
    })
  }
  readFileList(directory, useSubdirectories, extList)
  // 生成需要的对象
  const res = filesList.map(item => ({
    
    
    path: item,
    data: require(item),
    ...getPathInfo(item)
  }))

  return res
}

const fileList = autoLoadFile(path.join(__dirname, './langs'))
console.log(fileList)

Output result

In autoLoadFile.jsthe next directoryautoLoadFile.js

 node autoLoadFile.js

Output result

[
  {
    
    
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app/en.js',
    data: {
    
     lang: 'app-en' },
    root: '/',
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app',
    base: 'en.js',
    ext: '.js',
    name: 'en'
  },
  {
    
    
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app/zh.js',
    data: {
    
     lang: 'app-中文' },
    root: '/',
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app',
    base: 'zh.js',
    ext: '.js',
    name: 'zh'
  },
  {
    
    
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/en.js',
    data: {
    
     lang: 'en' },
    root: '/',
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs',
    base: 'en.js',
    ext: '.js',
    name: 'en'
  },
  {
    
    
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/zh.js',
    data: {
    
     lang: '中文' },
    root: '/',
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs',
    base: 'zh.js',
    ext: '.js',
    name: 'zh'
  }
]

Guess you like

Origin blog.csdn.net/qq_39953537/article/details/108665214