diff --git a/src/index.js b/src/index.js index 47437d1..b5b6c61 100644 --- a/src/index.js +++ b/src/index.js @@ -9,33 +9,29 @@ const ES6_BROWSER_EMPTY = resolve( __dirname, '../src/empty.js' ); // which deploy both ESM .mjs and CommonJS .js files as ESM. const DEFAULT_EXTS = [ '.mjs', '.js', '.json', '.node' ]; -let readFileCache = {}; const readFileAsync = file => new Promise((fulfil, reject) => fs.readFile(file, (err, contents) => err ? reject(err) : fulfil(contents))); const statAsync = file => new Promise((fulfil, reject) => fs.stat(file, (err, contents) => err ? reject(err) : fulfil(contents))); -function cachedReadFile (file, cb) { - if (file in readFileCache === false) { - readFileCache[file] = readFileAsync(file).catch(err => { - delete readFileCache[file]; - throw err; - }); - } - readFileCache[file].then(contents => cb(null, contents), cb); -} - -let isFileCache = {}; -function cachedIsFile (file, cb) { - if (file in isFileCache === false) { - isFileCache[file] = statAsync(file) - .then( - stat => stat.isFile(), - err => { - if (err.code === 'ENOENT') return false; - delete isFileCache[file]; - throw err; - }); - } - isFileCache[file].then(contents => cb(null, contents), cb); -} +const cache = fn => { + const cache = new Map(); + const wrapped = (param, done) => { + if (cache.has(param) === false) { + cache.set(param, fn(param).catch(err => { + cache.delete(param); + throw err; + })); + } + return cache.get(param).then(result => done(null, result), done); + }; + wrapped.clear = () => cache.clear(); + return wrapped; +}; +const ignoreENOENT = err => { + if (err.code === 'ENOENT') return false; + throw err; +}; +const readFileCached = cache(readFileAsync); +const isDirCached = cache(file => statAsync(file).then(stat => stat.isDirectory(), ignoreENOENT)); +const isFileCached = cache(file => statAsync(file).then(stat => stat.isFile(), ignoreENOENT)); function getMainFields (options) { let mainFields; @@ -99,8 +95,9 @@ export default function nodeResolve ( options = {} ) { }, generateBundle () { - isFileCache = {}; - readFileCache = {}; + readFileCached.clear(); + isFileCached.clear(); + isDirCached.clear(); }, resolveId ( importee, importer ) { @@ -180,8 +177,9 @@ export default function nodeResolve ( options = {} ) { } return pkg; }, - readFile: cachedReadFile, - isFile: cachedIsFile, + readFile: readFileCached, + isFile: isFileCached, + isDirectory: isDirCached, extensions: extensions };