mirror of https://github.com/status-im/metro.git
packager: GlobalTransformCache: make key globalized
Reviewed By: davidaurelio Differential Revision: D4835217 fbshipit-source-id: b43456e1e1f83c849a887b07f4f01f8ed0e9df4b
This commit is contained in:
parent
c1a2a5e942
commit
d1ea86b84c
|
@ -17,7 +17,7 @@ const debug = require('debug');
|
||||||
const invariant = require('fbjs/lib/invariant');
|
const invariant = require('fbjs/lib/invariant');
|
||||||
|
|
||||||
import type Server from './src/Server';
|
import type Server from './src/Server';
|
||||||
import type GlobalTransformCache from './src/lib/GlobalTransformCache';
|
import type {GlobalTransformCache} from './src/lib/GlobalTransformCache';
|
||||||
import type {Reporter} from './src/lib/reporting';
|
import type {Reporter} from './src/lib/reporting';
|
||||||
import type {HasteImpl} from './src/node-haste/Module';
|
import type {HasteImpl} from './src/node-haste/Module';
|
||||||
|
|
||||||
|
|
|
@ -46,13 +46,19 @@ import type {
|
||||||
TransformOptions,
|
TransformOptions,
|
||||||
} from '../JSTransformer/worker/worker';
|
} from '../JSTransformer/worker/worker';
|
||||||
import type {Reporter} from '../lib/reporting';
|
import type {Reporter} from '../lib/reporting';
|
||||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||||
|
|
||||||
|
export type ExtraTransformOptions = {
|
||||||
|
+inlineRequires?: {+blacklist: {[string]: true}} | boolean,
|
||||||
|
+preloadedModules?: Array<string> | false,
|
||||||
|
+ramGroups?: Array<string>,
|
||||||
|
};
|
||||||
|
|
||||||
export type GetTransformOptions = (
|
export type GetTransformOptions = (
|
||||||
mainModuleName: string,
|
mainModuleName: string,
|
||||||
options: {},
|
options: {},
|
||||||
getDependencies: string => Promise<Array<string>>,
|
getDependencies: string => Promise<Array<string>>,
|
||||||
) => {} | Promise<{}>;
|
) => ExtraTransformOptions | Promise<ExtraTransformOptions>;
|
||||||
|
|
||||||
type Asset = {
|
type Asset = {
|
||||||
__packager_asset: boolean,
|
__packager_asset: boolean,
|
||||||
|
|
|
@ -36,15 +36,19 @@ type Transformer = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TransformOptions = {
|
export type TransformOptions = {
|
||||||
|
+dev: boolean,
|
||||||
generateSourceMaps: boolean,
|
generateSourceMaps: boolean,
|
||||||
|
+hot: boolean,
|
||||||
|
+inlineRequires: {+blacklist: {[string]: true}} | boolean,
|
||||||
platform: string,
|
platform: string,
|
||||||
preloadedModules?: Array<string>,
|
preloadedModules?: Array<string> | false,
|
||||||
projectRoots: Array<string>,
|
projectRoots: Array<string>,
|
||||||
ramGroups?: Array<string>,
|
ramGroups?: Array<string>,
|
||||||
} & BabelTransformOptions;
|
} & BabelTransformOptions;
|
||||||
|
|
||||||
export type Options = {
|
export type Options = {
|
||||||
+dev: boolean,
|
+dev: boolean,
|
||||||
|
+extern?: boolean,
|
||||||
+minify: boolean,
|
+minify: boolean,
|
||||||
platform: string,
|
platform: string,
|
||||||
transform: TransformOptions,
|
transform: TransformOptions,
|
||||||
|
|
|
@ -24,7 +24,7 @@ import type {Reporter} from '../lib/reporting';
|
||||||
import type {TransformCode} from '../node-haste/Module';
|
import type {TransformCode} from '../node-haste/Module';
|
||||||
import type Cache from '../node-haste/Cache';
|
import type Cache from '../node-haste/Cache';
|
||||||
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
||||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||||
|
|
||||||
type MinifyCode = (filePath: string, code: string, map: SourceMap) =>
|
type MinifyCode = (filePath: string, code: string, map: SourceMap) =>
|
||||||
Promise<{code: string, map: SourceMap}>;
|
Promise<{code: string, map: SourceMap}>;
|
||||||
|
|
|
@ -34,7 +34,7 @@ import type Bundle from '../Bundler/Bundle';
|
||||||
import type HMRBundle from '../Bundler/HMRBundle';
|
import type HMRBundle from '../Bundler/HMRBundle';
|
||||||
import type {Reporter} from '../lib/reporting';
|
import type {Reporter} from '../lib/reporting';
|
||||||
import type {GetTransformOptions} from '../Bundler';
|
import type {GetTransformOptions} from '../Bundler';
|
||||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||||
import type {SourceMap, Symbolicate} from './symbolicate';
|
import type {SourceMap, Symbolicate} from './symbolicate';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -16,22 +16,53 @@ const FetchError = require('node-fetch/lib/fetch-error');
|
||||||
|
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
const imurmurhash = require('imurmurhash');
|
|
||||||
const jsonStableStringify = require('json-stable-stringify');
|
const jsonStableStringify = require('json-stable-stringify');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
|
import type {
|
||||||
|
Options as TransformWorkerOptions,
|
||||||
|
TransformOptions,
|
||||||
|
} from '../JSTransformer/worker/worker';
|
||||||
import type {CachedResult, GetTransformCacheKey} from './TransformCache';
|
import type {CachedResult, GetTransformCacheKey} from './TransformCache';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The API that a global transform cache must comply with. To implement a
|
||||||
|
* custom cache, implement this interface and pass it as argument to the
|
||||||
|
* application's top-level `Server` class.
|
||||||
|
*/
|
||||||
|
export type GlobalTransformCache = {
|
||||||
|
/**
|
||||||
|
* Synchronously determine if it is worth trying to fetch a result from the
|
||||||
|
* cache. This can be used, for instance, to exclude sets of options we know
|
||||||
|
* will never be cached.
|
||||||
|
*/
|
||||||
|
shouldFetch(props: FetchProps): boolean,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to fetch a result. It doesn't actually need to fetch from a server,
|
||||||
|
* the global cache could be instantiated locally for example.
|
||||||
|
*/
|
||||||
|
fetch(props: FetchProps): Promise<?CachedResult>,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to store a result, without waiting for the success or failure of the
|
||||||
|
* operation. Consequently, the actual storage operation could be done at a
|
||||||
|
* much later point if desired. It is recommended to actually have this
|
||||||
|
* function be a no-op in production, and only do the storage operation from
|
||||||
|
* a script running on your Continuous Integration platform.
|
||||||
|
*/
|
||||||
|
store(props: FetchProps, result: CachedResult): void,
|
||||||
|
};
|
||||||
|
|
||||||
type FetchResultURIs = (keys: Array<string>) => Promise<Map<string, string>>;
|
type FetchResultURIs = (keys: Array<string>) => Promise<Map<string, string>>;
|
||||||
type FetchResultFromURI = (uri: string) => Promise<?CachedResult>;
|
type FetchResultFromURI = (uri: string) => Promise<?CachedResult>;
|
||||||
type StoreResults = (resultsByKey: Map<string, CachedResult>) => Promise<void>;
|
type StoreResults = (resultsByKey: Map<string, CachedResult>) => Promise<void>;
|
||||||
|
|
||||||
type FetchProps = {
|
export type FetchProps = {
|
||||||
filePath: string,
|
filePath: string,
|
||||||
sourceCode: string,
|
sourceCode: string,
|
||||||
getTransformCacheKey: GetTransformCacheKey,
|
getTransformCacheKey: GetTransformCacheKey,
|
||||||
transformOptions: TransformOptions,
|
transformOptions: TransformWorkerOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
type URI = string;
|
type URI = string;
|
||||||
|
@ -98,29 +129,6 @@ class KeyResultStore {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The transform options contain absolute paths. This can contain, for example,
|
|
||||||
* the username if someone works their home directory (very likely). We get rid
|
|
||||||
* of this local data for the global cache, otherwise nobody would share the
|
|
||||||
* same cache keys. The project roots should not be needed as part of the cache
|
|
||||||
* key as they should not affect the transformation of a single particular file.
|
|
||||||
*/
|
|
||||||
function globalizeTransformOptions(
|
|
||||||
options: TransformOptions,
|
|
||||||
): TransformOptions {
|
|
||||||
const {transform} = options;
|
|
||||||
if (transform == null) {
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...options,
|
|
||||||
transform: {
|
|
||||||
...transform,
|
|
||||||
projectRoots: [],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TransformProfile = {+dev: boolean, +minify: boolean, +platform: string};
|
export type TransformProfile = {+dev: boolean, +minify: boolean, +platform: string};
|
||||||
|
|
||||||
function profileKey({dev, minify, platform}: TransformProfile): string {
|
function profileKey({dev, minify, platform}: TransformProfile): string {
|
||||||
|
@ -177,11 +185,12 @@ function validateCachedResult(cachedResult: mixed): ?CachedResult {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GlobalTransformCache {
|
class URIBasedGlobalTransformCache {
|
||||||
|
|
||||||
_fetcher: KeyURIFetcher;
|
_fetcher: KeyURIFetcher;
|
||||||
_fetchResultFromURI: FetchResultFromURI;
|
_fetchResultFromURI: FetchResultFromURI;
|
||||||
_profileSet: TransformProfileSet;
|
_profileSet: TransformProfileSet;
|
||||||
|
_optionsHasher: OptionsHasher;
|
||||||
_store: ?KeyResultStore;
|
_store: ?KeyResultStore;
|
||||||
|
|
||||||
static FetchFailedError;
|
static FetchFailedError;
|
||||||
|
@ -194,31 +203,34 @@ class GlobalTransformCache {
|
||||||
* of returning the content directly allows for independent and parallel
|
* of returning the content directly allows for independent and parallel
|
||||||
* fetching of each result, that may be arbitrarily large JSON blobs.
|
* fetching of each result, that may be arbitrarily large JSON blobs.
|
||||||
*/
|
*/
|
||||||
constructor(
|
constructor(props: {
|
||||||
fetchResultURIs: FetchResultURIs,
|
|
||||||
fetchResultFromURI: FetchResultFromURI,
|
fetchResultFromURI: FetchResultFromURI,
|
||||||
storeResults: ?StoreResults,
|
fetchResultURIs: FetchResultURIs,
|
||||||
profiles: Iterable<TransformProfile>,
|
profiles: Iterable<TransformProfile>,
|
||||||
) {
|
rootPath: string,
|
||||||
this._fetcher = new KeyURIFetcher(fetchResultURIs);
|
storeResults: StoreResults | null,
|
||||||
this._profileSet = new TransformProfileSet(profiles);
|
}) {
|
||||||
this._fetchResultFromURI = fetchResultFromURI;
|
this._fetcher = new KeyURIFetcher(props.fetchResultURIs);
|
||||||
if (storeResults != null) {
|
this._profileSet = new TransformProfileSet(props.profiles);
|
||||||
this._store = new KeyResultStore(storeResults);
|
this._fetchResultFromURI = props.fetchResultFromURI;
|
||||||
|
this._optionsHasher = new OptionsHasher(props.rootPath);
|
||||||
|
if (props.storeResults != null) {
|
||||||
|
this._store = new KeyResultStore(props.storeResults);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a key for identifying uniquely a source file.
|
* Return a key for identifying uniquely a source file.
|
||||||
*/
|
*/
|
||||||
static keyOf(props: FetchProps) {
|
keyOf(props: FetchProps) {
|
||||||
const stableOptions = globalizeTransformOptions(props.transformOptions);
|
const hash = crypto.createHash('sha1');
|
||||||
const digest = crypto.createHash('sha1').update([
|
const {sourceCode, filePath, transformOptions} = props;
|
||||||
jsonStableStringify(stableOptions),
|
this._optionsHasher.hashTransformWorkerOptions(hash, transformOptions);
|
||||||
props.getTransformCacheKey(props.sourceCode, props.filePath, props.transformOptions),
|
const cacheKey = props.getTransformCacheKey(sourceCode, filePath, transformOptions);
|
||||||
imurmurhash(props.sourceCode).result().toString(),
|
hash.update(JSON.stringify(cacheKey));
|
||||||
].join('$')).digest('hex');
|
hash.update(crypto.createHash('sha1').update(sourceCode).digest('hex'));
|
||||||
return `${digest}-${path.basename(props.filePath)}`;
|
const digest = hash.digest('hex');
|
||||||
|
return `${digest}-${path.basename(filePath)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -249,8 +261,8 @@ class GlobalTransformCache {
|
||||||
* waiting a little time before retring if experience shows it's useful.
|
* waiting a little time before retring if experience shows it's useful.
|
||||||
*/
|
*/
|
||||||
static fetchResultFromURI(uri: string): Promise<CachedResult> {
|
static fetchResultFromURI(uri: string): Promise<CachedResult> {
|
||||||
return GlobalTransformCache._fetchResultFromURI(uri).catch(error => {
|
return URIBasedGlobalTransformCache._fetchResultFromURI(uri).catch(error => {
|
||||||
if (!GlobalTransformCache.shouldRetryAfterThatError(error)) {
|
if (!URIBasedGlobalTransformCache.shouldRetryAfterThatError(error)) {
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
return this._fetchResultFromURI(uri);
|
return this._fetchResultFromURI(uri);
|
||||||
|
@ -284,7 +296,7 @@ class GlobalTransformCache {
|
||||||
* key yet, or an error happened, processed separately.
|
* key yet, or an error happened, processed separately.
|
||||||
*/
|
*/
|
||||||
async fetch(props: FetchProps): Promise<?CachedResult> {
|
async fetch(props: FetchProps): Promise<?CachedResult> {
|
||||||
const uri = await this._fetcher.fetch(GlobalTransformCache.keyOf(props));
|
const uri = await this._fetcher.fetch(this.keyOf(props));
|
||||||
if (uri == null) {
|
if (uri == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -293,12 +305,92 @@ class GlobalTransformCache {
|
||||||
|
|
||||||
store(props: FetchProps, result: CachedResult) {
|
store(props: FetchProps, result: CachedResult) {
|
||||||
if (this._store != null) {
|
if (this._store != null) {
|
||||||
this._store.store(GlobalTransformCache.keyOf(props), result);
|
this._store.store(this.keyOf(props), result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GlobalTransformCache.FetchFailedError = FetchFailedError;
|
class OptionsHasher {
|
||||||
|
_rootPath: string;
|
||||||
|
|
||||||
module.exports = GlobalTransformCache;
|
constructor(rootPath: string) {
|
||||||
|
this._rootPath = rootPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function is extra-conservative with how it hashes the transform
|
||||||
|
* options. In particular:
|
||||||
|
*
|
||||||
|
* * we need to hash paths relative to the root, not the absolute paths,
|
||||||
|
* otherwise everyone would have a different cache, defeating the
|
||||||
|
* purpose of global cache;
|
||||||
|
* * we need to reject any additional field we do not know of, because
|
||||||
|
* they could contain absolute path, and we absolutely want to process
|
||||||
|
* these.
|
||||||
|
*
|
||||||
|
* Theorically, Flow could help us prevent any other field from being here by
|
||||||
|
* using *exact* object type. In practice, the transform options are a mix of
|
||||||
|
* many different fields including the optional Babel fields, and some serious
|
||||||
|
* cleanup will be necessary to enable rock-solid typing.
|
||||||
|
*/
|
||||||
|
hashTransformWorkerOptions(hash: crypto$Hash, options: TransformWorkerOptions): crypto$Hash {
|
||||||
|
const {dev, minify, platform, transform, extern, ...unknowns} = options;
|
||||||
|
const unknownKeys = Object.keys(unknowns);
|
||||||
|
if (unknownKeys.length > 0) {
|
||||||
|
const message = `these worker option fields are unknown: ${JSON.stringify(unknownKeys)}`;
|
||||||
|
throw new CannotHashOptionsError(message);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-undef, no-bitwise
|
||||||
|
hash.update(new Buffer([+dev | +minify << 1 | +!!extern << 2]));
|
||||||
|
hash.update(JSON.stringify(platform));
|
||||||
|
return this.hashTransformOptions(hash, transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The transform options contain absolute paths. This can contain, for
|
||||||
|
* example, the username if someone works their home directory (very likely).
|
||||||
|
* We get rid of this local data for the global cache, otherwise nobody would
|
||||||
|
* share the same cache keys. The project roots should not be needed as part
|
||||||
|
* of the cache key as they should not affect the transformation of a single
|
||||||
|
* particular file.
|
||||||
|
*/
|
||||||
|
hashTransformOptions(hash: crypto$Hash, options: TransformOptions): crypto$Hash {
|
||||||
|
const {generateSourceMaps, dev, hot, inlineRequires, platform,
|
||||||
|
preloadedModules, projectRoots, ramGroups, ...unknowns} = options;
|
||||||
|
const unknownKeys = Object.keys(unknowns);
|
||||||
|
if (unknownKeys.length > 0) {
|
||||||
|
const message = `these transform option fields are unknown: ${JSON.stringify(unknownKeys)}`;
|
||||||
|
throw new CannotHashOptionsError(message);
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
hash.update(new Buffer([
|
||||||
|
// eslint-disable-next-line no-bitwise
|
||||||
|
+dev | +generateSourceMaps << 1 | +hot << 2 | +!!inlineRequires << 3,
|
||||||
|
]));
|
||||||
|
hash.update(JSON.stringify(platform));
|
||||||
|
let relativeBlacklist = [];
|
||||||
|
if (typeof inlineRequires === 'object') {
|
||||||
|
relativeBlacklist = this.relativizeFilePaths(Object.keys(inlineRequires.blacklist));
|
||||||
|
}
|
||||||
|
const relativeProjectRoots = this.relativizeFilePaths(projectRoots);
|
||||||
|
const optionTuple = [relativeBlacklist, preloadedModules, relativeProjectRoots, ramGroups];
|
||||||
|
hash.update(JSON.stringify(optionTuple));
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
relativizeFilePaths(filePaths: Array<string>): Array<string> {
|
||||||
|
return filePaths.map(filepath => path.relative(this._rootPath, filepath));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CannotHashOptionsError extends Error {
|
||||||
|
constructor(message: string) {
|
||||||
|
super();
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
URIBasedGlobalTransformCache.FetchFailedError = FetchFailedError;
|
||||||
|
|
||||||
|
module.exports = {URIBasedGlobalTransformCache, CannotHashOptionsError};
|
||||||
|
|
|
@ -15,8 +15,9 @@ jest.useRealTimers();
|
||||||
const fetchMock = jest.fn();
|
const fetchMock = jest.fn();
|
||||||
jest.mock('node-fetch', () => fetchMock);
|
jest.mock('node-fetch', () => fetchMock);
|
||||||
|
|
||||||
const GlobalTransformCache = require('../GlobalTransformCache');
|
const {URIBasedGlobalTransformCache} = require('../GlobalTransformCache');
|
||||||
const FetchError = require('node-fetch/lib/fetch-error');
|
const FetchError = require('node-fetch/lib/fetch-error');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
async function fetchResultURIs(keys: Array<string>): Promise<Map<string, string>> {
|
async function fetchResultURIs(keys: Array<string>): Promise<Map<string, string>> {
|
||||||
return new Map(keys.map(key => [key, `http://globalcache.com/${key}`]));
|
return new Map(keys.map(key => [key, `http://globalcache.com/${key}`]));
|
||||||
|
@ -33,14 +34,27 @@ async function fetchResultFromURI(uri: string): Promise<?CachedResult> {
|
||||||
describe('GlobalTransformCache', () => {
|
describe('GlobalTransformCache', () => {
|
||||||
|
|
||||||
it('fetches results', async () => {
|
it('fetches results', async () => {
|
||||||
const cache = new GlobalTransformCache(fetchResultURIs, fetchResultFromURI, null, [
|
const cache = new URIBasedGlobalTransformCache({
|
||||||
{dev: true, minify: false, platform: 'ios'},
|
fetchResultFromURI,
|
||||||
]);
|
fetchResultURIs,
|
||||||
|
profiles: [{dev: true, minify: false, platform: 'ios'}],
|
||||||
|
rootPath: __dirname,
|
||||||
|
storeResults: null,
|
||||||
|
});
|
||||||
const transformOptions = {
|
const transformOptions = {
|
||||||
dev: true,
|
dev: true,
|
||||||
minify: false,
|
minify: false,
|
||||||
platform: 'ios',
|
platform: 'ios',
|
||||||
transform: {},
|
transform: {
|
||||||
|
generateSourceMaps: false,
|
||||||
|
dev: false,
|
||||||
|
hot: false,
|
||||||
|
inlineRequires: false,
|
||||||
|
platform: 'ios',
|
||||||
|
preloadedModules: [],
|
||||||
|
projectRoots: [path.join(__dirname, 'root')],
|
||||||
|
ramGroups: [],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const result = await Promise.all([cache.fetch({
|
const result = await Promise.all([cache.fetch({
|
||||||
filePath: 'foo.js',
|
filePath: 'foo.js',
|
||||||
|
@ -73,7 +87,8 @@ describe('GlobalTransformCache', () => {
|
||||||
|
|
||||||
it('fetches result', async () => {
|
it('fetches result', async () => {
|
||||||
fetchMock.mockImplementation(defaultFetchMockImpl);
|
fetchMock.mockImplementation(defaultFetchMockImpl);
|
||||||
const result = await GlobalTransformCache.fetchResultFromURI('http://globalcache.com/foo');
|
const result = await URIBasedGlobalTransformCache
|
||||||
|
.fetchResultFromURI('http://globalcache.com/foo');
|
||||||
expect(result).toMatchSnapshot();
|
expect(result).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -82,7 +97,8 @@ describe('GlobalTransformCache', () => {
|
||||||
fetchMock.mockImplementation(defaultFetchMockImpl);
|
fetchMock.mockImplementation(defaultFetchMockImpl);
|
||||||
throw new FetchError('timeout!', 'request-timeout');
|
throw new FetchError('timeout!', 'request-timeout');
|
||||||
});
|
});
|
||||||
const result = await GlobalTransformCache.fetchResultFromURI('http://globalcache.com/foo');
|
const result = await URIBasedGlobalTransformCache
|
||||||
|
.fetchResultFromURI('http://globalcache.com/foo');
|
||||||
expect(result).toMatchSnapshot();
|
expect(result).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -19,12 +19,12 @@ Object {
|
||||||
exports[`GlobalTransformCache fetches results 1`] = `
|
exports[`GlobalTransformCache fetches results 1`] = `
|
||||||
Array [
|
Array [
|
||||||
Object {
|
Object {
|
||||||
"code": "/* code from http://globalcache.com/17ce731dadd36402f15abb768843cb5e8ecf9ca7-foo.js */",
|
"code": "/* code from http://globalcache.com/fb94b11256237327e4eef5daa08bad33573b3781-foo.js */",
|
||||||
"dependencies": Array [],
|
"dependencies": Array [],
|
||||||
"dependencyOffsets": Array [],
|
"dependencyOffsets": Array [],
|
||||||
},
|
},
|
||||||
Object {
|
Object {
|
||||||
"code": "/* code from http://globalcache.com/d78572916bd877b6ac0e819e99be9fc2954f0e00-bar.js */",
|
"code": "/* code from http://globalcache.com/b902b4a8841fcea2919c2fe9b21e68d96dff59c9-bar.js */",
|
||||||
"dependencies": Array [],
|
"dependencies": Array [],
|
||||||
"dependencyOffsets": Array [],
|
"dependencyOffsets": Array [],
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,7 +23,7 @@ const jsonStableStringify = require('json-stable-stringify');
|
||||||
const {join: joinPath, relative: relativePath, extname} = require('path');
|
const {join: joinPath, relative: relativePath, extname} = require('path');
|
||||||
|
|
||||||
import type {TransformedCode, Options as TransformOptions} from '../JSTransformer/worker/worker';
|
import type {TransformedCode, Options as TransformOptions} from '../JSTransformer/worker/worker';
|
||||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||||
import type {SourceMap} from '../lib/SourceMap';
|
import type {SourceMap} from '../lib/SourceMap';
|
||||||
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
||||||
import type {ReadTransformProps} from '../lib/TransformCache';
|
import type {ReadTransformProps} from '../lib/TransformCache';
|
||||||
|
|
|
@ -16,7 +16,7 @@ const Module = require('./Module');
|
||||||
const Package = require('./Package');
|
const Package = require('./Package');
|
||||||
const Polyfill = require('./Polyfill');
|
const Polyfill = require('./Polyfill');
|
||||||
|
|
||||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||||
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
||||||
import type {Reporter} from '../lib/reporting';
|
import type {Reporter} from '../lib/reporting';
|
||||||
import type Cache from './Cache';
|
import type Cache from './Cache';
|
||||||
|
|
|
@ -38,7 +38,7 @@ const {
|
||||||
const {EventEmitter} = require('events');
|
const {EventEmitter} = require('events');
|
||||||
|
|
||||||
import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
|
import type {Options as TransformOptions} from '../JSTransformer/worker/worker';
|
||||||
import type GlobalTransformCache from '../lib/GlobalTransformCache';
|
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||||
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
import type {GetTransformCacheKey} from '../lib/TransformCache';
|
||||||
import type {Reporter} from '../lib/reporting';
|
import type {Reporter} from '../lib/reporting';
|
||||||
import type {ModuleMap} from './DependencyGraph/ResolutionRequest';
|
import type {ModuleMap} from './DependencyGraph/ResolutionRequest';
|
||||||
|
|
Loading…
Reference in New Issue