Skip to content

Instantly share code, notes, and snippets.

@ogonkov
Last active February 12, 2018 09:30
Show Gist options
  • Save ogonkov/2be0b8e6ee696d93415bd71b0a239b71 to your computer and use it in GitHub Desktop.
Save ogonkov/2be0b8e6ee696d93415bd71b0a239b71 to your computer and use it in GitHub Desktop.
Get webpack entries asynchronously from dirs

Convert a bunch of dirs to Webpack entries

  foo
  |- bar
  |  `- index.js
  |- qux
  `- baz
     `- index.js
  {
    entry: {
      bar: './bar/index.js',
      baz: './baz/index.js'
    }
  }
/* eslint-env node */
const path = require('path');
const fs = require('fs');
const util = require('util');
const readdir = util.promisify(fs.readdir);
const fstat = util.promisify(fs.fstat);
const open = util.promisify(fs.open);
/**
* @param {string} dir
* @returns {Promise<boolean>}
*/
async function isDir(dir) {
try {
const fd = await open(dir, 'r');
const stat = await fstat(fd);
return stat.isDirectory();
} catch (ex) {
return false;
}
}
/**
* @param {string} file
* @returns {Promise<boolean>}
*/
async function isFile(file) {
try {
const fd = await open(file, 'r');
const stat = await fstat(fd);
return stat.isFile();
} catch (ex) {
return false;
}
}
/**
* @param {array} dirs
* @returns {array}
*/
function hasResult(dirs) {
return dirs.filter((dir) => dir);
}
/**
* @param {string} baseDir
* @param {function} matcher
* @param {string|string[]} [extraPath]
* @returns {Function}
*/
function getCheck(baseDir, matcher, extraPath = []) {
return function(checkedEntry) {
return matcher(
path.join.apply(path, [baseDir, checkedEntry].concat(extraPath))
).then((result) => result && checkedEntry);
};
}
/**
* @param {string} baseDir
* @param {array} entries
* @param {function} matcher
* @param {string|string[]} [extraPath]
* @returns {Promise<string[]>}
*/
function checkAll(baseDir, entries, matcher, extraPath) {
return Promise.all(
entries.map(getCheck(baseDir, matcher, extraPath))
).then(hasResult);
}
/**
* @param {string} baseDir
* @param {string} indexFile
* @param {object} hashmap
* @param {string} dir
* @returns {object}
*/
function toConfig(baseDir, indexFile, hashmap, dir) {
return {
...hashmap,
[dir]: path.join(baseDir, dir, indexFile)
};
}
/**
* @param {string} baseDir
* @param {string} [indexFile='index.js']
* @returns {Promise<string[]>}
*/
exports.getEntries = async function(baseDir, indexFile = 'index.js') {
const dirContent = await readdir(baseDir);
return checkAll(baseDir, dirContent, isDir)
.then((dirs) => checkAll(baseDir, dirs, isFile, indexFile))
.then((dirs) => dirs.reduce(toConfig.bind(null, baseDir, indexFile), {}));
};
/* eslint-env node */
const getEntries = require('get-entries').getEntries;
module.exports = {
entries: async function() {
return await getEntries(__dirname, 'main.js');
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment