Updates to node-haste adapter
Reviewed By: matryoshcow Differential Revision: D4197864 fbshipit-source-id: 31bc4b0fb51ea77fac09fdd0f8180e984e05087a
This commit is contained in:
parent
2af1de283c
commit
3a52efa614
|
@ -11,7 +11,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const {dirname, parse} = require('path');
|
||||
const {dirname, join, parse} = require('path');
|
||||
|
||||
module.exports = class FastFS {
|
||||
directories: Set<string>;
|
||||
|
@ -24,6 +24,18 @@ module.exports = class FastFS {
|
|||
this.files = new Set(files);
|
||||
}
|
||||
|
||||
closest(path: string, fileName: string): ?string {
|
||||
let {dir, root} = parse(path);
|
||||
do {
|
||||
const candidate = join(dir, fileName);
|
||||
if (this.files.has(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
dir = dirname(dir);
|
||||
} while (dir !== '.' && dir !== root);
|
||||
return null;
|
||||
}
|
||||
|
||||
dirExists(path: string) {
|
||||
return this.directories.has(path);
|
||||
}
|
||||
|
@ -47,8 +59,8 @@ function buildDirectorySet(files) {
|
|||
files.forEach(path => {
|
||||
let {dir, root} = parse(path);
|
||||
while (dir !== '.' && dir !== root && !directories.has(dir)) {
|
||||
directories.add(path);
|
||||
dir = dirname(path);
|
||||
directories.add(dir);
|
||||
dir = dirname(dir);
|
||||
}
|
||||
});
|
||||
return directories;
|
||||
|
|
|
@ -12,15 +12,22 @@
|
|||
'use strict';
|
||||
|
||||
import type {TransformedFile} from '../types.flow';
|
||||
import type {ModuleCache} from './node-haste.flow';
|
||||
|
||||
module.exports = class Module {
|
||||
hasteID: Promise<?string>;
|
||||
moduleCache: ModuleCache;
|
||||
name: Promise<string>;
|
||||
path: string;
|
||||
type: 'Module';
|
||||
|
||||
constructor(path: string, info: Promise<TransformedFile>) {
|
||||
constructor(
|
||||
path: string,
|
||||
moduleCache: ModuleCache,
|
||||
info: Promise<TransformedFile>,
|
||||
) {
|
||||
this.hasteID = info.then(({hasteID}) => hasteID);
|
||||
this.moduleCache = moduleCache;
|
||||
this.name = this.hasteID.then(name => name || getName(path));
|
||||
this.path = path;
|
||||
this.type = 'Module';
|
||||
|
@ -30,6 +37,10 @@ module.exports = class Module {
|
|||
return this.name;
|
||||
}
|
||||
|
||||
getPackage() {
|
||||
return this.moduleCache.getPackageOf(this.path);
|
||||
}
|
||||
|
||||
isHaste() {
|
||||
return this.hasteID.then(Boolean);
|
||||
}
|
||||
|
|
|
@ -15,16 +15,19 @@ const Module = require('./Module');
|
|||
const Package = require('./Package');
|
||||
|
||||
import type {PackageData, TransformedFile} from '../types.flow';
|
||||
import type {FastFS} from './node-haste.flow';
|
||||
|
||||
type GetFn<T> = (path: string) => Promise<T>;
|
||||
|
||||
module.exports = class ModuleCache {
|
||||
fastfs: FastFS;
|
||||
getPackageData: GetFn<PackageData>;
|
||||
getTransformedFile: GetFn<TransformedFile>;
|
||||
modules: Map<string, Module>;
|
||||
packages: Map<string, Package>;
|
||||
|
||||
constructor(getTransformedFile: GetFn<TransformedFile>) {
|
||||
constructor(fastfs: FastFS, getTransformedFile: GetFn<TransformedFile>) {
|
||||
this.fastfs = fastfs;
|
||||
this.getTransformedFile = getTransformedFile;
|
||||
this.getPackageData = path => getTransformedFile(path).then(
|
||||
f => f.package || Promise.reject(new Error(`"${path}" does not exist`))
|
||||
|
@ -40,7 +43,7 @@ module.exports = class ModuleCache {
|
|||
getModule(path: string) {
|
||||
let m = this.modules.get(path);
|
||||
if (!m) {
|
||||
m = new Module(path, this.getTransformedFile(path));
|
||||
m = new Module(path, this, this.getTransformedFile(path));
|
||||
this.modules.set(path, m);
|
||||
}
|
||||
return m;
|
||||
|
@ -54,4 +57,9 @@ module.exports = class ModuleCache {
|
|||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
getPackageOf(filePath: string) {
|
||||
const candidate = this.fastfs.closest(filePath, 'package.json');
|
||||
return candidate != null ? this.getPackage(candidate) : null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,11 +17,13 @@ import type {PackageData} from '../types.flow';
|
|||
|
||||
module.exports = class Package {
|
||||
data: Promise<PackageData>;
|
||||
path: string;
|
||||
root: string;
|
||||
type: 'Package';
|
||||
|
||||
constructor(packagePath: string, data: Promise<PackageData>) {
|
||||
this.data = data;
|
||||
this.path = packagePath;
|
||||
this.root = path.dirname(packagePath);
|
||||
this.type = 'Package';
|
||||
}
|
||||
|
@ -52,6 +54,10 @@ module.exports = class Package {
|
|||
return this.data.then(p => p.name);
|
||||
}
|
||||
|
||||
isHaste() {
|
||||
return this.data.then(p => !!p.name);
|
||||
}
|
||||
|
||||
redirectRequire(name: string) {
|
||||
// Copied from node-haste/Package.js
|
||||
return this.data.then(data => {
|
||||
|
|
|
@ -24,14 +24,17 @@ export type Module = {
|
|||
path: Path,
|
||||
type: 'Module',
|
||||
getName(): Promise<ModuleID>,
|
||||
getPackage(): ?Package,
|
||||
isHaste(): Promise<boolean>,
|
||||
};
|
||||
|
||||
export type Package = {
|
||||
type: 'Package',
|
||||
path: Path,
|
||||
root: Path,
|
||||
type: 'Package',
|
||||
getMain(): Promise<Path>,
|
||||
getName(): Promise<ModuleID>,
|
||||
isHaste(): Promise<boolean>,
|
||||
redirectRequire(id: ModuleID): Promise<Path | false>,
|
||||
};
|
||||
|
||||
|
@ -40,10 +43,12 @@ export interface ModuleCache {
|
|||
getAssetModule(path: Path): Module,
|
||||
getModule(path: Path): Module,
|
||||
getPackage(path: Path): Package,
|
||||
getPackageOf(path: Path): ?Package,
|
||||
}
|
||||
|
||||
export type FastFS = {
|
||||
dirExists(path: Path): boolean,
|
||||
closest(path: string, fileName: string): ?string,
|
||||
fileExists(path: Path): boolean,
|
||||
getAllFiles(): Array<Path>,
|
||||
matches(directory: Path, pattern: RegExp): Array<Path>,
|
||||
|
@ -63,17 +68,19 @@ declare class DeprecatedAssetMap {
|
|||
export type DeprecatedAssetMapT = DeprecatedAssetMap;
|
||||
|
||||
type HasteMapOptions = {|
|
||||
allowRelativePaths: boolean,
|
||||
extensions: Extensions,
|
||||
fastfs: FastFS,
|
||||
moduleCache: ModuleCache,
|
||||
preferNativePlatform: true,
|
||||
helpers: DependencyGraphHelpers,
|
||||
moduleCache: ModuleCache,
|
||||
platforms: Platforms,
|
||||
preferNativePlatform: true,
|
||||
|};
|
||||
|
||||
declare class HasteMap {
|
||||
// node-haste/DependencyGraph/HasteMap.js
|
||||
constructor(options: HasteMapOptions): void,
|
||||
build(): Promise<Object>,
|
||||
}
|
||||
export type HasteMapT = HasteMap;
|
||||
|
||||
|
|
|
@ -31,22 +31,21 @@ const HasteMap: Class<HasteMapT> = require('../../node-haste/DependencyGraph/Has
|
|||
const Module = require('./Module');
|
||||
const ModuleCache = require('./ModuleCache');
|
||||
const ResolutionRequest: Class<ResolutionRequestT> = require('../../node-haste/DependencyGraph/ResolutionRequest');
|
||||
const defaults = require('../../../../defaults');
|
||||
|
||||
type ResolveOptions = {
|
||||
type ResolveOptions = {|
|
||||
assetExts: Extensions,
|
||||
extraNodeModules: {[id: string]: string},
|
||||
providesModuleNodeModules: Array<string>,
|
||||
transformedFiles: {[path: Path]: TransformedFile},
|
||||
};
|
||||
|};
|
||||
|
||||
const platforms = new Set(['android', 'ios']);
|
||||
const platforms = new Set(defaults.platforms);
|
||||
const returnTrue = () => true;
|
||||
|
||||
exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
||||
const {
|
||||
assetExts,
|
||||
extraNodeModules,
|
||||
providesModuleNodeModules,
|
||||
transformedFiles,
|
||||
} = options;
|
||||
const files = Object.keys(transformedFiles);
|
||||
|
@ -57,7 +56,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
|||
|
||||
const helpers = new DependencyGraphHelpers({
|
||||
assetExts,
|
||||
providesModuleNodeModules,
|
||||
providesModuleNodeModules: defaults.providesModuleNodeModules,
|
||||
});
|
||||
const deprecatedAssetMap = new DeprecatedAssetMap({
|
||||
assetExts,
|
||||
|
@ -67,8 +66,9 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
|||
});
|
||||
|
||||
const fastfs = new FastFS(files);
|
||||
const moduleCache = new ModuleCache(getTransformedFile);
|
||||
const moduleCache = new ModuleCache(fastfs, getTransformedFile);
|
||||
const hasteMap = new HasteMap({
|
||||
allowRelativePaths: true,
|
||||
extensions: ['js', 'json'],
|
||||
fastfs,
|
||||
helpers,
|
||||
|
@ -77,6 +77,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
|||
preferNativePlatform: true,
|
||||
});
|
||||
|
||||
const hasteMapBuilt = hasteMap.build();
|
||||
const resolutionRequests = {};
|
||||
return (id, source, platform, _, callback) => {
|
||||
let resolutionRequest = resolutionRequests[platform];
|
||||
|
@ -95,11 +96,13 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
|
|||
});
|
||||
}
|
||||
|
||||
const from = new Module(source, getTransformedFile(source));
|
||||
resolutionRequest.resolveDependency(from, id).then(
|
||||
// nextTick to escape promise error handling
|
||||
module => process.nextTick(callback, null, module.path),
|
||||
error => process.nextTick(callback, error),
|
||||
);
|
||||
const from = new Module(source, moduleCache, getTransformedFile(source));
|
||||
hasteMapBuilt
|
||||
.then(() => resolutionRequest.resolveDependency(from, id))
|
||||
.then(
|
||||
// nextTick to escape promise error handling
|
||||
module => process.nextTick(callback, null, module.path),
|
||||
error => process.nextTick(callback, error),
|
||||
);
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue