Dynamically export a module by reading all files in a directory in Node.js

狂风中的少年 提交于 2021-02-11 12:53:28

问题


So today i was trying read all default exports from some directory which has index.js. Try to wrap it inside one object and export it back again. Is there a better way to handle this ?

 export default (() => require('fs')
            .readdirSync(__dirname)
            .filter(fileName => !!/.js$/ig.test(fileName))
            .map(fileName => fileName.split('.')[0])
            .reduce((defaultExportObj, nextFileName) => {
                try {
                    return {
                        ...defaultExportObj,
                        [nextFileName]: require(__dirname + `/${nextFileName}`),
                    };
                }catch(err) { throw err; }
            }, {}))();

回答1:


I guess i'd do something like this - not sure if this is better - w/e better is ^^

webpack: require.context

function expDefault(path, mode = "sync"){

    const modules = {}
    const context = require.context(path, false, /\.js$/, mode)
    context.keys().forEach(file => {
        const name = fileName.replace(/^.+\/([^/]+)\.js$/, "$1")
        modules[name] = context(name).default
    })
    return modules
}
export default expDefault(__dirname)



回答2:


This seems like mostly personal style preferences, but I'd just use a plain for/of loop and some if statements instead of 3 intermediate arrays.

const moduleList = {};
const files = require('fs').readdirSync(__dirname);
const jsExt = /.js$/i;

for (const filename of files) {
    if (jsExt.test(filename)) {
        const baseFilename = filename.slice(-3);
        moduleList[baseFilename] = require(__dirname + '/' + baseFilename),
    }
}

export default moduleList;

Comments:

  1. Creates regex object once rather than multiple times
  2. No need for g flag on the regex
  3. Use filename.slice(-3) to remove known file extension because .split('.')[0] doesn't get you the string after last . and windows allows multiple . in a filename. Also, no need to search for where the . is as you already know where it is since it's a known extension.
  4. Only one array created from readdirSync() rather than two additional intermediate arrays
  5. The array is only iterated once instead of four times.
  6. There's no point to try {...} catch(err) { throw err; } unless you're going to put something else in the catch block.
  7. A mix of template literals and string addition in __dirname + `/${nextFileName}` doesn't make sense to me. Use one or the other.

If you have some reason to want all symbols private, you could modify it to this:

export default (function() {
    const moduleList = {};
    const files = require('fs').readdirSync(__dirname);
    const jsExt = /.js$/i;

    for (const filename of files) {
        if (jsExt.test(filename)) {
            const baseFilename = filename.slice(-3);
            moduleList[baseFilename] = require(__dirname + '/' + baseFilename),
        }
    }
    return moduleList;
})();    


来源:https://stackoverflow.com/questions/58457014/dynamically-export-a-module-by-reading-all-files-in-a-directory-in-node-js

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!