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'; } from './resolve';
export type { export type {
AssetFileResolution, AssetFileResolution,
CustomResolver,
FileAndDirCandidates, FileAndDirCandidates,
FileCandidates, FileCandidates,
FileResolution, FileResolution,

View File

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

View File

@ -42,3 +42,5 @@ export type FileCandidates =
+filePathPrefix: string, +filePathPrefix: string,
+candidateExts: $ReadOnlyArray<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 Module from '../node-haste/Module';
import type {BabelSourceMap} from '@babel/core'; import type {BabelSourceMap} from '@babel/core';
import type {CacheStore} from 'metro-cache'; import type {CacheStore} from 'metro-cache';
import type {CustomResolver} from 'metro-resolver';
import type { import type {
MetroSourceMapSegmentTuple, MetroSourceMapSegmentTuple,
MetroSourceMap, MetroSourceMap,
@ -98,6 +99,7 @@ export type Options = {|
+providesModuleNodeModules?: Array<string>, +providesModuleNodeModules?: Array<string>,
+reporter: Reporter, +reporter: Reporter,
+resetCache: boolean, +resetCache: boolean,
+resolveRequest: ?CustomResolver,
+sourceExts: Array<string>, +sourceExts: Array<string>,
+transformCache: TransformCache, +transformCache: TransformCache,
+transformModulePath: string, +transformModulePath: string,
@ -163,6 +165,7 @@ class Bundler {
providesModuleNodeModules: providesModuleNodeModules:
opts.providesModuleNodeModules || defaults.providesModuleNodeModules, opts.providesModuleNodeModules || defaults.providesModuleNodeModules,
reporter: opts.reporter, reporter: opts.reporter,
resolveRequest: opts.resolveRequest,
resetCache: opts.resetCache, resetCache: opts.resetCache,
sourceExts: opts.sourceExts, sourceExts: opts.sourceExts,
transformCode: this._cachedTransformCode.bind(this), 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 {DynamicRequiresBehavior} from './ModuleGraph/worker/collectDependencies';
import type {IncomingMessage, ServerResponse} from 'http'; import type {IncomingMessage, ServerResponse} from 'http';
import type {CacheStore} from 'metro-cache'; import type {CacheStore} from 'metro-cache';
import type {CustomResolver} from 'metro-resolver';
type Middleware = (IncomingMessage, ServerResponse, ?() => mixed) => mixed; type Middleware = (IncomingMessage, ServerResponse, ?() => mixed) => mixed;
@ -141,6 +142,12 @@ export type ConfigT = {
*/ */
postProcessBundleSourcemap: PostProcessBundleSourcemap, 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: * Path to a require-able module that exports:
* - a `getHasteName(filePath)` method that returns `hasteName` for module at * - a `getHasteName(filePath)` method that returns `hasteName` for module at
@ -186,6 +193,7 @@ const DEFAULT = ({
getUseGlobalHotkey: () => true, getUseGlobalHotkey: () => true,
postMinifyProcess: x => x, postMinifyProcess: x => x,
postProcessBundleSourcemap: ({code, map, outFileName}) => ({code, map}), postProcessBundleSourcemap: ({code, map, outFileName}) => ({code, map}),
resolveRequest: null,
getModulesRunBeforeMainModule: () => [], getModulesRunBeforeMainModule: () => [],
getWorkerPath: () => null, getWorkerPath: () => null,
}: ConfigT); }: ConfigT);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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