问题
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:
- Creates regex object once rather than multiple times
- No need for
g
flag on the regex - 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. - Only one array created from
readdirSync()
rather than two additional intermediate arrays - The array is only iterated once instead of four times.
- There's no point to
try {...} catch(err) { throw err; }
unless you're going to put something else in thecatch
block. - 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