Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Commit

Permalink
perf: add cached version of isDir (#218)
Browse files Browse the repository at this point in the history
* perf: add cached version of `isDir`

* refactor: DRY up cache functions

* refactor: use Map for cache over Object

* refactor: rename variables for clarity
  • Loading branch information
keithamus authored and lukastaegert committed May 11, 2019
1 parent 952033a commit e7eef7f
Showing 1 changed file with 27 additions and 29 deletions.
56 changes: 27 additions & 29 deletions src/index.js
Expand Up @@ -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;
Expand Down Expand Up @@ -99,8 +95,9 @@ export default function nodeResolve ( options = {} ) {
},

generateBundle () {
isFileCache = {};
readFileCache = {};
readFileCached.clear();
isFileCached.clear();
isDirCached.clear();
},

resolveId ( importee, importer ) {
Expand Down Expand Up @@ -180,8 +177,9 @@ export default function nodeResolve ( options = {} ) {
}
return pkg;
},
readFile: cachedReadFile,
isFile: cachedIsFile,
readFile: readFileCached,
isFile: isFileCached,
isDirectory: isDirCached,
extensions: extensions
};

Expand Down

0 comments on commit e7eef7f

Please sign in to comment.