Sometimes, you have multiple providers for the same functionality. For example, while working on my book recommendation website, I had to fetch listings for books from various different vendors (Amazon, BookDepository and such).
The initial solution was to just use imports and then put them into an array:
import amazonUs from './vendors/amazonUs';
import amazonUk from './vendors/amazonUk';
import amazonCa from './vendors/amazonCa';
import amazonDe from './vendors/amazonDe';
import amazonEs from './vendors/amazonEs';
import amazonFr from './vendors/amazonFr';
import abeBooks from './vendors/abeBooks';
import bookDepository from './vendors/bookDepository';
const vendors = [
amazonUs,
amazonUk,
amazonCa,
amazonDe,
amazonEs,
amazonFr,
abeBooks,
bookDepository
];
export default function fetchListings(book) {
return Promise.all(vendors.map(vendor => vendor.fetchListing(book)));
}
As you can imagine, this gets pretty cumbersome when you have to support more more than a few vendors (Amazon alone has 12 locales which need to be handled separately). In order to add a new vendor, you have to create a new file, then import that file here and also add it to the array.
However, if you’re using Node or a CommonJS-enabled environment, you can do something like this:
import fs from 'fs';
const vendors = fs.readdirSync(`${__dirname}/vendors`)
.map(vendor => require(`${__dirname}/vendors/${vendor}`).default);
export default function fetchListings(book) {
return Promise.all(vendors.map(vendor => vendor.fetchListing(book)));
}
To add a new vendor, all you have to do is create the file. It’s not much, but it helps streamline the process.
As a final note, if you’re doing this often, you could write a small helper function:
import fs from 'fs';
export function requireAllFrom(dirName) {
return fs.readdirSync(dirName).map(file => require(`${dirName}/${file}`));
}
Elsewhere:
const vendors = requireAllFrom(`${__dirname}/vendors`)
.map(v => v.default);
I’ve also used this for:
- Creating unit tests that use fixtures and expected file output
- Adding custom plugins to Babel
- Creating multiple loggers for analytics (i.e. console and Mixpanel)