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