mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
ImportScanner: cache file stats and package.jsons
This helps performance quite a bit, taking what could otherwise be (say) 10 seconds down to a couple seconds in ImportScanner for an app that imports a thousand files.
This commit is contained in:
@@ -65,6 +65,9 @@ export default class ImportScanner {
|
||||
this.watchSet = watchSet;
|
||||
this.absPathToOutputIndex = {};
|
||||
this.outputFiles = [];
|
||||
|
||||
this._statCache = new Map;
|
||||
this._pkgJsonCache = new Map;
|
||||
}
|
||||
|
||||
addInputFiles(files) {
|
||||
@@ -386,30 +389,40 @@ export default class ImportScanner {
|
||||
}
|
||||
|
||||
_joinAndStat(...joinArgs) {
|
||||
const path = pathNormalize(pathJoin(...joinArgs));
|
||||
const exactStat = statOrNull(path);
|
||||
const exactResult = exactStat && { path, stat: exactStat };
|
||||
if (exactResult && exactStat.isFile()) {
|
||||
return exactResult;
|
||||
const joined = pathJoin(...joinArgs);
|
||||
if (this._statCache.has(joined)) {
|
||||
return this._statCache.get(joined);
|
||||
}
|
||||
|
||||
for (let ext in extensions) {
|
||||
if (has(extensions, ext)) {
|
||||
const pathWithExt = path + ext;
|
||||
const stat = statOrNull(pathWithExt);
|
||||
if (stat) {
|
||||
return { path: pathWithExt, stat };
|
||||
const path = pathNormalize(joined);
|
||||
const exactStat = statOrNull(path);
|
||||
const exactResult = exactStat && { path, stat: exactStat };
|
||||
let result = null;
|
||||
if (exactResult && exactStat.isFile()) {
|
||||
result = exactResult;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
for (let ext in extensions) {
|
||||
if (has(extensions, ext)) {
|
||||
const pathWithExt = path + ext;
|
||||
const stat = statOrNull(pathWithExt);
|
||||
if (stat) {
|
||||
result = { path: pathWithExt, stat };
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (exactResult && exactStat.isDirectory()) {
|
||||
if (!result && exactResult && exactStat.isDirectory()) {
|
||||
// After trying all available file extensions, fall back to the
|
||||
// original result if it was a directory.
|
||||
return exactResult;
|
||||
result = exactResult;
|
||||
}
|
||||
|
||||
return null;
|
||||
this._statCache.set(joined, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
_resolveAbsolute(file, id) {
|
||||
@@ -465,15 +478,25 @@ export default class ImportScanner {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
_readPkgJson(path) {
|
||||
if (this._pkgJsonCache.has(path)) {
|
||||
return this._pkgJsonCache.get(path);
|
||||
}
|
||||
|
||||
let result = null;
|
||||
try {
|
||||
result = JSON.parse(this._readFile(path).data);
|
||||
} catch (e) {
|
||||
// leave result null
|
||||
}
|
||||
|
||||
this._pkgJsonCache.set(path, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
_resolvePkgJsonMain(dirPath, seenDirPaths) {
|
||||
const pkgJsonPath = pathJoin(dirPath, "package.json");
|
||||
|
||||
let pkg;
|
||||
try {
|
||||
pkg = JSON.parse(this._readFile(pkgJsonPath).data);
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
const pkg = this._readPkgJson(pkgJsonPath);
|
||||
|
||||
if (pkg && isString(pkg.main)) {
|
||||
// The "main" field of package.json does not have to begin with ./
|
||||
@@ -529,7 +552,8 @@ export default class ImportScanner {
|
||||
}
|
||||
|
||||
each(["_readFile", "_findImportedModuleIdentifiers",
|
||||
"_getInstallPath", "_tryToResolveImportedPath"], funcName => {
|
||||
"_getInstallPath", "_tryToResolveImportedPath",
|
||||
"_resolvePkgJsonMain"], funcName => {
|
||||
ImportScanner.prototype[funcName] = Profile(
|
||||
`ImportScanner#${funcName}`, ImportScanner.prototype[funcName]);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user