用 node 实现类似 webpack 的 require.context()功能

简介:最近在写 nuxt 的项目,因为是服务端渲染,需要加载大量国际化文件,一个一个导入太费劲,于是想自动导入,首先想到的是 webpack 的 require.context()功能,可是服务端渲染用不了。于是自己用 node 写了一个文件加载器。

文件目录

1
.
2
├── autoLoadFile.js
3
└── langs
4
    ├── app
5
    │   ├── en.js
6
    │   └── zh.js
7
    ├── en.js
8
    └── zh.js

langs/en.js

1
// langs/app/en.js内容和这一样,加了app前缀
2
const en = {
3
  lang: 'en'
4
}
5
6
module.exports = en

langs/zh.js

1
// langs/app/en.js内容和这一样,加了app前缀
2
const zh = {
3
  lang: '中文''
4
}
5
6
module.exports = zh

核心实现 autoLoadFile.js

1
#!/usr/bin/env node
2
const path = require('path')
3
const fs = require('fs')
4
const getPathInfo = p => path.parse(p)
5
6
/**
7
 * @description // 递归读取文件,类似于webpack的require.context()
8
 * @time 2020-9-12
9
 *
10
 * @param {String} directory 文件目录
11
 * @param {Boolean} useSubdirectories 是否查询子目录,默认false
12
 * @param {array} extList 查询文件后缀,默认 ['.js']
13
 *
14
 */
15
function autoLoadFile(directory, useSubdirectories = false, extList = ['.js']) {
16
  const filesList = []
17
  // 递归读取文件
18
  function readFileList(directory, useSubdirectories, extList) {
19
    const files = fs.readdirSync(directory)
20
    files.forEach(item => {
21
      const fullPath = path.join(directory, item)
22
      const stat = fs.statSync(fullPath)
23
      if (stat.isDirectory() && useSubdirectories) {
24
        readFileList(path.join(directory, item), useSubdirectories, extList)
25
      } else {
26
        const info = getPathInfo(fullPath)
27
        extList.includes(info.ext) && filesList.push(fullPath)
28
      }
29
    })
30
  }
31
  readFileList(directory, useSubdirectories, extList)
32
  // 生成需要的对象
33
  const res = filesList.map(item => ({
34
    path: item,
35
    data: require(item),
36
    ...getPathInfo(item)
37
  }))
38
39
  return res
40
}
41
42
const fileList = autoLoadFile(path.join(__dirname, './langs'))
43
console.log(fileList)

输出结果

autoLoadFile.js 所在目录下执行autoLoadFile.js

1
node autoLoadFile.js

输出结果

1
[
2
  {
3
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app/en.js',
4
    data: { lang: 'app-en' },
5
    root: '/',
6
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app',
7
    base: 'en.js',
8
    ext: '.js',
9
    name: 'en'
10
  },
11
  {
12
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app/zh.js',
13
    data: { lang: 'app-中文' },
14
    root: '/',
15
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/app',
16
    base: 'zh.js',
17
    ext: '.js',
18
    name: 'zh'
19
  },
20
  {
21
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/en.js',
22
    data: { lang: 'en' },
23
    root: '/',
24
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs',
25
    base: 'en.js',
26
    ext: '.js',
27
    name: 'en'
28
  },
29
  {
30
    path: '/Users/youqun/Saifu-Chemical-Admin/tests/langs/zh.js',
31
    data: { lang: '中文' },
32
    root: '/',
33
    dir: '/Users/youqun/Saifu-Chemical-Admin/tests/langs',
34
    base: 'zh.js',
35
    ext: '.js',
36
    name: 'zh'
37
  }
38
]