packager: Package.js: make read()-based API sync

Reviewed By: davidaurelio

Differential Revision: D4745885

fbshipit-source-id: 3d327e5ca91fcbe7ec1d30ff8e6135b415074aa4
This commit is contained in:
Jean Lauliac 2017-03-22 06:41:14 -07:00 committed by Facebook Github Bot
parent fc95a312b9
commit ebd732784b
2 changed files with 80 additions and 83 deletions

View File

@ -232,7 +232,7 @@ class ResolutionRequest {
let p = fromModule.getPackage(); let p = fromModule.getPackage();
if (p) { if (p) {
p = p.redirectRequire(toModuleName); p = Promise.resolve(p.redirectRequire(toModuleName));
} else { } else {
p = Promise.resolve(toModuleName); p = Promise.resolve(toModuleName);
} }
@ -470,13 +470,11 @@ class ResolutionRequest {
const packageJsonPath = path.join(potentialDirPath, 'package.json'); const packageJsonPath = path.join(potentialDirPath, 'package.json');
if (this._hasteFS.exists(packageJsonPath)) { if (this._hasteFS.exists(packageJsonPath)) {
return this._moduleCache.getPackage(packageJsonPath) const main = this._moduleCache.getPackage(packageJsonPath).getMain();
.getMain().then( return this._tryResolve(
main => this._tryResolve( () => this._loadAsFile(main, fromModule, toModule),
() => this._loadAsFile(main, fromModule, toModule), () => this._loadAsDir(main, fromModule, toModule),
() => this._loadAsDir(main, fromModule, toModule) );
)
);
} }
return this._loadAsFile( return this._loadAsFile(

View File

@ -17,6 +17,13 @@ const path = require('path');
import type Cache from './Cache'; import type Cache from './Cache';
type PackageContent = {
name: string,
'react-native': mixed,
browser: mixed,
main: ?string,
};
class Package { class Package {
path: string; path: string;
@ -24,12 +31,7 @@ class Package {
type: string; type: string;
_cache: Cache; _cache: Cache;
_reading: Promise<{ _content: ?PackageContent;
name: string,
'react-native': mixed,
browser: mixed,
main: ?string,
}>;
constructor({file, cache}: { constructor({file, cache}: {
file: string, file: string,
@ -39,39 +41,39 @@ class Package {
this.root = path.dirname(this.path); this.root = path.dirname(this.path);
this.type = 'Package'; this.type = 'Package';
this._cache = cache; this._cache = cache;
this._content = null;
} }
getMain() { getMain() {
return this.read().then(json => { const json = this.read();
var replacements = getReplacements(json); var replacements = getReplacements(json);
if (typeof replacements === 'string') { if (typeof replacements === 'string') {
return path.join(this.root, replacements); return path.join(this.root, replacements);
} }
let main = json.main || 'index'; let main = json.main || 'index';
if (replacements && typeof replacements === 'object') { if (replacements && typeof replacements === 'object') {
main = replacements[main] || main = replacements[main] ||
replacements[main + '.js'] || replacements[main + '.js'] ||
replacements[main + '.json'] || replacements[main + '.json'] ||
replacements[main.replace(/(\.js|\.json)$/, '')] || replacements[main.replace(/(\.js|\.json)$/, '')] ||
main; main;
} }
/* $FlowFixMe: `getReplacements` doesn't validate the return value. */ /* $FlowFixMe: `getReplacements` doesn't validate the return value. */
return path.join(this.root, main); return path.join(this.root, main);
});
} }
isHaste() { isHaste() {
return this._cache.get(this.path, 'package-haste', () => return this._cache.get(this.path, 'package-haste', () =>
this.read().then(json => !!json.name) Promise.resolve(!!this.read().name)
); );
} }
getName(): Promise<string> { getName(): Promise<string> {
return this._cache.get(this.path, 'package-name', () => return this._cache.get(this.path, 'package-name', () =>
this.read().then(json => json.name) Promise.resolve(this.read().name)
); );
} }
@ -79,66 +81,63 @@ class Package {
this._cache.invalidate(this.path); this._cache.invalidate(this.path);
} }
redirectRequire(name: string) { redirectRequire(name: string): string | false {
return this.read().then(json => { const json = this.read();
var replacements = getReplacements(json); const replacements = getReplacements(json);
if (!replacements || typeof replacements !== 'object') {
return name;
}
if (!isAbsolutePath(name)) {
const replacement = replacements[name];
// support exclude with "someDependency": false
return replacement === false
? false
: replacement || name;
}
let relPath = './' + path.relative(this.root, name);
if (path.sep !== '/') {
relPath = relPath.replace(new RegExp('\\' + path.sep, 'g'), '/');
}
let redirect = replacements[relPath];
// false is a valid value
if (redirect == null) {
redirect = replacements[relPath + '.js'];
if (redirect == null) {
redirect = replacements[relPath + '.json'];
}
}
// support exclude with "./someFile": false
if (redirect === false) {
return false;
}
if (redirect) {
return path.join(
this.root,
/* $FlowFixMe: `getReplacements` doesn't validate the return value. */
redirect
);
}
if (!replacements || typeof replacements !== 'object') {
return name; return name;
}); }
}
read() { if (!isAbsolutePath(name)) {
if (!this._reading) { const replacement = replacements[name];
this._reading = new Promise( // support exclude with "someDependency": false
resolve => resolve(JSON.parse(fs.readFileSync(this.path, 'utf8'))) return replacement === false
? false
/* $FlowFixMe: type of replacements is not being validated */
: replacement || name;
}
let relPath = './' + path.relative(this.root, name);
if (path.sep !== '/') {
relPath = relPath.replace(new RegExp('\\' + path.sep, 'g'), '/');
}
let redirect = replacements[relPath];
// false is a valid value
if (redirect == null) {
redirect = replacements[relPath + '.js'];
if (redirect == null) {
redirect = replacements[relPath + '.json'];
}
}
// support exclude with "./someFile": false
if (redirect === false) {
return false;
}
if (redirect) {
return path.join(
this.root,
/* $FlowFixMe: `getReplacements` doesn't validate the return value. */
redirect
); );
} }
return this._reading; return name;
}
read(): PackageContent {
if (this._content == null) {
this._content = JSON.parse(fs.readFileSync(this.path, 'utf8'));
}
return this._content;
} }
} }
function getReplacements(pkg) { function getReplacements(pkg: PackageContent): mixed {
let rn = pkg['react-native']; let rn = pkg['react-native'];
let browser = pkg.browser; let browser = pkg.browser;
if (rn == null) { if (rn == null) {