Adds an experimental hook for custom resolutions

Reviewed By: mjesun

Differential Revision: D7337022

fbshipit-source-id: fea1ee345e4d3b5713fed6cdc33869fbba6f21e2
This commit is contained in:
Maël Nison 2018-04-05 08:54:52 -07:00 committed by Facebook Github Bot
parent 5714c450f7
commit 203bb0ddfd
12 changed files with 54 additions and 5 deletions

View File

@ -18,6 +18,7 @@ export type {
} from './resolve';
export type {
AssetFileResolution,
CustomResolver,
FileAndDirCandidates,
FileCandidates,
FileResolution,

View File

@ -20,6 +20,7 @@ const path = require('path');
import type {
AssetFileResolution,
CustomResolver,
FileAndDirCandidates,
FileCandidates,
FileResolution,
@ -29,9 +30,10 @@ import type {
export type ResolutionContext = ModulePathContext &
HasteContext & {
originModulePath: string,
allowHaste: boolean,
extraNodeModules: ?{[string]: string},
originModulePath: string,
resolveRequest?: ?CustomResolver,
};
function resolve(
@ -39,9 +41,13 @@ function resolve(
moduleName: string,
platform: string | null,
): Resolution {
if (isRelativeImport(moduleName) || isAbsolutePath(moduleName)) {
if (
!context.resolveRequest &&
(isRelativeImport(moduleName) || isAbsolutePath(moduleName))
) {
return resolveModulePath(context, moduleName, platform);
}
const realModuleName = context.redirectModulePath(moduleName);
// exclude
if (realModuleName === false) {
@ -49,7 +55,10 @@ function resolve(
}
const {originModulePath} = context;
if (isRelativeImport(realModuleName) || isAbsolutePath(realModuleName)) {
if (
!context.resolveRequest &&
(isRelativeImport(realModuleName) || isAbsolutePath(realModuleName))
) {
// derive absolute path /.../node_modules/originModuleDir/realModuleName
const fromModuleParentIdx =
originModulePath.lastIndexOf('node_modules' + path.sep) + 13;
@ -61,8 +70,18 @@ function resolve(
return resolveModulePath(context, absPath, platform);
}
// At that point we only have module names that
// aren't relative paths nor absolute paths.
if (context.resolveRequest) {
try {
const resolution = context.resolveRequest(
moduleName,
context.originModulePath,
);
if (resolution) {
return {type: 'sourceFile', filePath: resolution};
}
} catch (error) {}
}
if (context.allowHaste) {
const normalizedName = normalizePath(realModuleName);
const result = resolveHasteName(context, normalizedName, platform);

View File

@ -42,3 +42,5 @@ export type FileCandidates =
+filePathPrefix: string,
+candidateExts: $ReadOnlyArray<string>,
|};
export type CustomResolver = (string, string) => string;

View File

@ -36,6 +36,7 @@ import type {Reporter} from '../lib/reporting';
import type Module from '../node-haste/Module';
import type {BabelSourceMap} from '@babel/core';
import type {CacheStore} from 'metro-cache';
import type {CustomResolver} from 'metro-resolver';
import type {
MetroSourceMapSegmentTuple,
MetroSourceMap,
@ -98,6 +99,7 @@ export type Options = {|
+providesModuleNodeModules?: Array<string>,
+reporter: Reporter,
+resetCache: boolean,
+resolveRequest: ?CustomResolver,
+sourceExts: Array<string>,
+transformCache: TransformCache,
+transformModulePath: string,
@ -163,6 +165,7 @@ class Bundler {
providesModuleNodeModules:
opts.providesModuleNodeModules || defaults.providesModuleNodeModules,
reporter: opts.reporter,
resolveRequest: opts.resolveRequest,
resetCache: opts.resetCache,
sourceExts: opts.sourceExts,
transformCode: this._cachedTransformCode.bind(this),

View File

@ -23,6 +23,7 @@ import type {TransformedCode} from './JSTransformer/worker';
import type {DynamicRequiresBehavior} from './ModuleGraph/worker/collectDependencies';
import type {IncomingMessage, ServerResponse} from 'http';
import type {CacheStore} from 'metro-cache';
import type {CustomResolver} from 'metro-resolver';
type Middleware = (IncomingMessage, ServerResponse, ?() => mixed) => mixed;
@ -141,6 +142,12 @@ export type ConfigT = {
*/
postProcessBundleSourcemap: PostProcessBundleSourcemap,
/**
* An optional function used to resolve requests. Ignored when the request can
* be resolved through Haste.
*/
resolveRequest: ?CustomResolver,
/**
* Path to a require-able module that exports:
* - a `getHasteName(filePath)` method that returns `hasteName` for module at
@ -186,6 +193,7 @@ const DEFAULT = ({
getUseGlobalHotkey: () => true,
postMinifyProcess: x => x,
postProcessBundleSourcemap: ({code, map, outFileName}) => ({code, map}),
resolveRequest: null,
getModulesRunBeforeMainModule: () => [],
getWorkerPath: () => null,
}: ConfigT);

View File

@ -29,10 +29,12 @@ const {ModuleMap} = require('jest-haste-map');
import type {Moduleish} from '../../node-haste/DependencyGraph/ResolutionRequest';
import type {ResolveFn, TransformedCodeFile} from '../types.flow';
import type {Extensions, Path} from './node-haste.flow';
import type {CustomResolver} from 'metro-resolver';
type ResolveOptions = {|
assetExts: Extensions,
extraNodeModules: {[id: string]: string},
resolveRequest?: ?CustomResolver,
+sourceExts: Extensions,
transformedFiles: {[path: Path]: TransformedCodeFile},
|};
@ -147,6 +149,7 @@ exports.createResolveFn = function(options: ResolveOptions): ResolveFn {
preferNativePlatform: true,
resolveAsset: (dirPath, assetName, platform) =>
assetResolutionCache.resolve(dirPath, assetName, platform),
resolveRequest: options.resolveRequest,
sourceExts,
});

View File

@ -54,6 +54,7 @@ import type {
} from '../Bundler';
import type {CacheStore} from 'metro-cache';
import type {Delta, Graph} from '../DeltaBundler';
import type {CustomResolver} from 'metro-resolver';
import type {MetroSourceMap} from 'metro-source-map';
import type {TransformCache} from '../lib/TransformCaching';
import type {Symbolicate} from './symbolicate/symbolicate';
@ -102,6 +103,7 @@ class Server {
maxWorkers: number,
minifierPath: string,
platforms: Array<string>,
resolveRequest: ?CustomResolver,
polyfillModuleNames: Array<string>,
postMinifyProcess: PostMinifyProcess,
postProcessBundleSourcemap: PostProcessBundleSourcemap,
@ -109,6 +111,7 @@ class Server {
providesModuleNodeModules?: Array<string>,
reporter: Reporter,
resetCache: boolean,
resolveRequest: ?CustomResolver,
+getModulesRunBeforeMainModule: (entryFilePath: string) => Array<string>,
+getRunModuleStatement: (number | string) => string,
silent: boolean,
@ -177,6 +180,7 @@ class Server {
providesModuleNodeModules: options.providesModuleNodeModules,
reporter,
resetCache: options.resetCache || false,
resolveRequest: options.resolveRequest,
silent: options.silent || false,
sourceExts: options.assetTransforms
? sourceExts.concat(assetExts)

View File

@ -141,6 +141,7 @@ async function runMetro({
providesModuleNodeModules,
resetCache,
reporter,
resolveRequest: normalizedConfig.resolveRequest,
sourceExts: normalizedConfig.assetTransforms
? sourceExts.concat(assetExts)
: sourceExts,

View File

@ -196,6 +196,7 @@ function toServerOptions(options: Options): ServerOptions {
providesModuleNodeModules: options.providesModuleNodeModules,
reporter: options.reporter,
resetCache: options.resetCache,
resolveRequest: options.resolveRequest,
silent: options.silent,
sourceExts: options.sourceExts,
transformCache: options.transformCache || TransformCaching.useTempDir(),

View File

@ -40,6 +40,7 @@ import type {ModuleMap} from './DependencyGraph/ModuleResolution';
import type {TransformCode} from './Module';
import type Package from './Package';
import type {HasteFS} from './types';
import type {CustomResolver} from 'metro-resolver';
type Options = {|
+assetExts: Array<string>,
@ -58,6 +59,7 @@ type Options = {|
+providesModuleNodeModules: Array<string>,
+reporter: Reporter,
+resetCache: boolean,
+resolveRequest: ?CustomResolver,
+sourceExts: Array<string>,
+transformCache: TransformCache,
+transformCode: TransformCode,
@ -192,6 +194,7 @@ class DependencyGraph extends EventEmitter {
preferNativePlatform: true,
resolveAsset: (dirPath, assetName, platform) =>
this._assetResolutionCache.resolve(dirPath, assetName, platform),
resolveRequest: this._opts.resolveRequest,
sourceExts: this._opts.sourceExts,
});
}

View File

@ -17,6 +17,7 @@ const path = require('path');
const util = require('util');
import type {
CustomResolver,
DoesFileExist,
IsAssetFile,
ResolveAsset,
@ -70,6 +71,7 @@ type Options<TModule, TPackage> = {|
+preferNativePlatform: boolean,
+moduleMap: ModuleMap,
+resolveAsset: ResolveAsset,
+resolveRequest: ?CustomResolver,
+sourceExts: Array<string>,
|};

View File

@ -23,6 +23,7 @@ import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
import type {TransformCache} from '../lib/TransformCaching';
import type {Reporter} from '../lib/reporting';
import type {CacheStore} from 'metro-cache';
import type {CustomResolver} from 'metro-resolver';
import type {
MetroSourceMap,
MetroSourceMapSegmentTuple,
@ -102,6 +103,7 @@ export type Options = {|
providesModuleNodeModules?: Array<string>,
reporter?: Reporter,
resetCache?: boolean,
resolveRequest: ?CustomResolver,
+getModulesRunBeforeMainModule: (entryPoint: string) => Array<string>,
silent?: boolean,
+sourceExts: ?Array<string>,