mirror of https://github.com/status-im/metro.git
Pass cacheStores
Reviewed By: davidaurelio Differential Revision: D7023425 fbshipit-source-id: 84d0d6585af4075bd7ac11ac3c97520caeae7b01
This commit is contained in:
parent
eab7030b2e
commit
7486444a0a
|
@ -12,14 +12,14 @@
|
|||
|
||||
import type {CacheStore} from 'metro-cache';
|
||||
|
||||
class Cache {
|
||||
_stores: $ReadOnlyArray<CacheStore>;
|
||||
class Cache<T> {
|
||||
_stores: $ReadOnlyArray<CacheStore<T>>;
|
||||
|
||||
constructor(stores: $ReadOnlyArray<CacheStore>) {
|
||||
constructor(stores: $ReadOnlyArray<CacheStore<T>>) {
|
||||
this._stores = stores;
|
||||
}
|
||||
|
||||
async get(key: Buffer): Promise<mixed> {
|
||||
async get(key: Buffer): Promise<?T> {
|
||||
const stores = this._stores;
|
||||
const length = stores.length;
|
||||
|
||||
|
@ -38,7 +38,7 @@ class Cache {
|
|||
return null;
|
||||
}
|
||||
|
||||
set(key: Buffer, value: mixed): void {
|
||||
set(key: Buffer, value: T): void {
|
||||
Promise.all(this._stores.map(store => store.set(key, value))).catch(err => {
|
||||
process.nextTick(() => {
|
||||
throw err;
|
||||
|
|
|
@ -52,6 +52,8 @@ describe('Cache', () => {
|
|||
});
|
||||
|
||||
it('awaits for promises on stores, even if they return undefined', async () => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
let resolve;
|
||||
|
||||
const store1 = createStore();
|
||||
|
@ -67,7 +69,9 @@ describe('Cache', () => {
|
|||
expect(store2.get).not.toHaveBeenCalled();
|
||||
|
||||
resolve(undefined);
|
||||
|
||||
await promise;
|
||||
jest.runAllTimers();
|
||||
|
||||
expect(store1.get).toHaveBeenCalledTimes(1);
|
||||
expect(store2.get).toHaveBeenCalledTimes(1);
|
||||
|
|
|
@ -12,6 +12,9 @@
|
|||
|
||||
const Cache = require('./Cache');
|
||||
|
||||
const stableHash = require('./stableHash');
|
||||
|
||||
export type {CacheStore} from './types.flow';
|
||||
|
||||
module.exports.Cache = Cache;
|
||||
module.exports.stableHash = stableHash;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
export type CacheStore = {
|
||||
get(key: Buffer): ?mixed | Promise<?mixed>,
|
||||
set(key: Buffer, value: mixed): void | Promise<void>,
|
||||
export type CacheStore<T> = {
|
||||
get(key: Buffer): ?T | Promise<?T>,
|
||||
set(key: Buffer, value: T): void | Promise<void>,
|
||||
};
|
||||
|
|
|
@ -34,6 +34,7 @@ var commonOptions = {
|
|||
allowBundleUpdates: false,
|
||||
assetExts: defaults.assetExts,
|
||||
assetRegistryPath: '/AssetRegistry.js',
|
||||
cacheStores: [],
|
||||
cacheVersion: 'smth',
|
||||
enableBabelRCLookup: true,
|
||||
extraNodeModules: {},
|
||||
|
|
|
@ -18,6 +18,7 @@ const defaults = require('../defaults');
|
|||
const fs = require('fs');
|
||||
const getTransformCacheKeyFn = require('../lib/getTransformCacheKeyFn');
|
||||
|
||||
const {Cache, stableHash} = require('metro-cache');
|
||||
const {
|
||||
toSegmentTuple,
|
||||
fromRawMappings,
|
||||
|
@ -25,12 +26,16 @@ const {
|
|||
} = require('metro-source-map');
|
||||
|
||||
import type {PostProcessModules} from '../DeltaBundler';
|
||||
import type {Options as JSTransformerOptions} from '../JSTransformer/worker';
|
||||
import type {
|
||||
Options as JSTransformerOptions,
|
||||
TransformedCode,
|
||||
} from '../JSTransformer/worker';
|
||||
import type {DynamicRequiresBehavior} from '../ModuleGraph/worker/collectDependencies';
|
||||
import type {GlobalTransformCache} from '../lib/GlobalTransformCache';
|
||||
import type {TransformCache} from '../lib/TransformCaching';
|
||||
import type {Reporter} from '../lib/reporting';
|
||||
import type {BabelSourceMap} from '@babel/core';
|
||||
import type {CacheStore} from 'metro-cache';
|
||||
import type {
|
||||
MetroSourceMapSegmentTuple,
|
||||
MetroSourceMap,
|
||||
|
@ -80,6 +85,7 @@ export type Options = {|
|
|||
+assetRegistryPath: string,
|
||||
+asyncRequireModulePath: string,
|
||||
+blacklistRE?: RegExp,
|
||||
+cacheStores: $ReadOnlyArray<CacheStore<TransformedCode>>,
|
||||
+cacheVersion: string,
|
||||
+dynamicDepsInPackages: DynamicRequiresBehavior,
|
||||
+enableBabelRCLookup: boolean,
|
||||
|
@ -108,16 +114,18 @@ export type Options = {|
|
|||
|
||||
class Bundler {
|
||||
_opts: Options;
|
||||
_cache: ?Cache<TransformedCode>;
|
||||
_transformer: Transformer;
|
||||
_depGraphPromise: Promise<DependencyGraph>;
|
||||
_projectRoots: $ReadOnlyArray<string>;
|
||||
_getTransformOptions: void | GetTransformOptions;
|
||||
|
||||
constructor(opts: Options) {
|
||||
this._opts = opts;
|
||||
|
||||
opts.projectRoots.forEach(verifyRootExists);
|
||||
|
||||
this._opts = opts;
|
||||
this._cache = opts.cacheStores.length ? new Cache(opts.cacheStores) : null;
|
||||
|
||||
this._transformer = new Transformer({
|
||||
asyncRequireModulePath: opts.asyncRequireModulePath,
|
||||
maxWorkers: opts.maxWorkers,
|
||||
|
@ -157,16 +165,7 @@ class Bundler {
|
|||
reporter: opts.reporter,
|
||||
resetCache: opts.resetCache,
|
||||
sourceExts: opts.sourceExts,
|
||||
transformCode: (module, code, transformCodeOptions) =>
|
||||
this._transformer.transform(
|
||||
module.path,
|
||||
module.localPath,
|
||||
code,
|
||||
module.isPolyfill(),
|
||||
transformCodeOptions,
|
||||
this._opts.assetExts,
|
||||
this._opts.assetRegistryPath,
|
||||
),
|
||||
transformCode: this._cachedTransformCode.bind(this),
|
||||
transformCache: opts.transformCache,
|
||||
watch: opts.watch,
|
||||
});
|
||||
|
@ -276,6 +275,50 @@ class Bundler {
|
|||
map: result.map ? toBabelSegments(result.map).map(toSegmentTuple) : [],
|
||||
};
|
||||
}
|
||||
|
||||
async _cachedTransformCode(
|
||||
module,
|
||||
code,
|
||||
transformCodeOptions,
|
||||
): Promise<TransformedCode> {
|
||||
const cache = this._cache;
|
||||
let result;
|
||||
let key;
|
||||
|
||||
// First, try getting the result from the cache if enabled.
|
||||
if (cache) {
|
||||
key = stableHash([
|
||||
module.localPath,
|
||||
code,
|
||||
transformCodeOptions,
|
||||
this._opts.assetExts,
|
||||
this._opts.assetRegistryPath,
|
||||
this._opts.cacheVersion,
|
||||
]);
|
||||
|
||||
result = await cache.get(key);
|
||||
}
|
||||
|
||||
// Second, if there was no result, compute it ourselves.
|
||||
if (!result) {
|
||||
result = await this._transformer.transform(
|
||||
module.path,
|
||||
module.localPath,
|
||||
code,
|
||||
module.isPolyfill(),
|
||||
transformCodeOptions,
|
||||
this._opts.assetExts,
|
||||
this._opts.assetRegistryPath,
|
||||
);
|
||||
}
|
||||
|
||||
// Third, propagate the result to all cache layers.
|
||||
if (key && cache) {
|
||||
cache.set(key, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function verifyRootExists(root) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import type {
|
|||
PostProcessBundleSourcemap,
|
||||
} from './Bundler';
|
||||
import type {PostProcessModules} from './DeltaBundler';
|
||||
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';
|
||||
|
@ -35,7 +36,7 @@ export type ConfigT = {
|
|||
/**
|
||||
* List of all store caches.
|
||||
*/
|
||||
cacheStores: Array<CacheStore>,
|
||||
cacheStores: Array<CacheStore<TransformedCode>>,
|
||||
|
||||
/**
|
||||
* Can be used to generate a key that will invalidate the whole metro cache
|
||||
|
|
|
@ -30,6 +30,7 @@ const defaults = require('../../defaults');
|
|||
const bundlerOptions = {
|
||||
allowBundleUpdates: false,
|
||||
assetExts: defaults.assetExts,
|
||||
cacheStores: [],
|
||||
cacheVersion: 'smth',
|
||||
enableBabelRCLookup: true,
|
||||
extraNodeModules: {},
|
||||
|
|
|
@ -40,12 +40,14 @@ import type {
|
|||
PostMinifyProcess,
|
||||
PostProcessBundleSourcemap,
|
||||
} from '../Bundler';
|
||||
import type {CacheStore} from 'metro-cache';
|
||||
import type {MetroSourceMap} from 'metro-source-map';
|
||||
import type {TransformCache} from '../lib/TransformCaching';
|
||||
import type {Symbolicate} from './symbolicate';
|
||||
import type {AssetData} from '../Assets';
|
||||
import type {RamBundleInfo} from '../DeltaBundler/Serializers';
|
||||
import type {PostProcessModules} from '../DeltaBundler';
|
||||
import type {TransformedCode} from '../JSTransformer/worker';
|
||||
const {
|
||||
Logger: {createActionStartEntry, createActionEndEntry, log},
|
||||
} = require('metro-core');
|
||||
|
@ -66,6 +68,7 @@ class Server {
|
|||
_opts: {
|
||||
assetExts: Array<string>,
|
||||
blacklistRE: void | RegExp,
|
||||
cacheStores: $ReadOnlyArray<CacheStore<TransformedCode>>,
|
||||
cacheVersion: string,
|
||||
createModuleIdFactory?: () => (path: string) => number,
|
||||
enableBabelRCLookup: boolean,
|
||||
|
@ -117,6 +120,7 @@ class Server {
|
|||
assetExts: options.assetTransforms ? [] : assetExts,
|
||||
assetRegistryPath: options.assetRegistryPath,
|
||||
blacklistRE: options.blacklistRE,
|
||||
cacheStores: options.cacheStores || [],
|
||||
cacheVersion: options.cacheVersion,
|
||||
dynamicDepsInPackages: options.dynamicDepsInPackages || 'throwAtRuntime',
|
||||
createModuleIdFactory: options.createModuleIdFactory,
|
||||
|
|
Loading…
Reference in New Issue