diff --git a/local-cli/bundle/buildBundle.js b/local-cli/bundle/buildBundle.js index afd7ef70d..c65f53434 100644 --- a/local-cli/bundle/buildBundle.js +++ b/local-cli/bundle/buildBundle.js @@ -73,6 +73,7 @@ function buildBundle( blacklistRE: config.getBlacklistRE(), extraNodeModules: config.extraNodeModules, getTransformOptions: config.getTransformOptions, + globalTransformCache: null, projectRoots: config.getProjectRoots(), providesModuleNodeModules: providesModuleNodeModules, resetCache: args.resetCache, diff --git a/packager/react-packager/react-packager.js b/packager/react-packager/react-packager.js index 86e5b929d..588a75254 100644 --- a/packager/react-packager/react-packager.js +++ b/packager/react-packager/react-packager.js @@ -16,12 +16,14 @@ const Logger = require('./src/Logger'); const debug = require('debug'); const invariant = require('fbjs/lib/invariant'); +import type GlobalTransformCache from './src/lib/GlobalTransformCache'; import type {Reporter} from './src/lib/reporting'; exports.createServer = createServer; exports.Logger = Logger; type Options = { + globalTransformCache: ?GlobalTransformCache, nonPersistent: boolean, projectRoots: Array, reporter?: Reporter, @@ -29,6 +31,7 @@ type Options = { }; type StrictOptions = { + globalTransformCache: ?GlobalTransformCache, nonPersistent: boolean, projectRoots: Array, reporter: Reporter, diff --git a/packager/react-packager/src/Bundler/index.js b/packager/react-packager/src/Bundler/index.js index 221ae418f..dc7016565 100644 --- a/packager/react-packager/src/Bundler/index.js +++ b/packager/react-packager/src/Bundler/index.js @@ -39,6 +39,7 @@ import type Module from '../node-haste/Module'; import type ResolutionResponse from '../node-haste/DependencyGraph/ResolutionResponse'; import type {Options as JSTransformerOptions, TransformOptions} from '../JSTransformer/worker/worker'; import type {Reporter} from '../lib/reporting'; +import type GlobalTransformCache from '../lib/GlobalTransformCache'; export type GetTransformOptions = ( mainModuleName: string, @@ -70,6 +71,7 @@ type Options = { cacheVersion: string, extraNodeModules: {}, getTransformOptions?: GetTransformOptions, + globalTransformCache: ?GlobalTransformCache, moduleFormat: string, platforms: Array, polyfillModuleNames: Array, @@ -150,6 +152,7 @@ class Bundler { blacklistRE: opts.blacklistRE, cache: this._cache, extraNodeModules: opts.extraNodeModules, + globalTransformCache: opts.globalTransformCache, minifyCode: this._transformer.minify, moduleFormat: opts.moduleFormat, platforms: opts.platforms, diff --git a/packager/react-packager/src/Resolver/index.js b/packager/react-packager/src/Resolver/index.js index a32b2fe88..e5f5a839d 100644 --- a/packager/react-packager/src/Resolver/index.js +++ b/packager/react-packager/src/Resolver/index.js @@ -23,6 +23,7 @@ import type {Options as TransformOptions} from '../JSTransformer/worker/worker'; import type {Reporter} from '../lib/reporting'; import type {TransformCode} from '../node-haste/Module'; import type Cache from '../node-haste/Cache'; +import type GlobalTransformCache from '../lib/GlobalTransformCache'; type MinifyCode = (filePath: string, code: string, map: SourceMap) => Promise<{code: string, map: SourceMap}>; @@ -32,6 +33,7 @@ type Options = { blacklistRE?: RegExp, cache: Cache, extraNodeModules?: {}, + globalTransformCache: ?GlobalTransformCache, minifyCode: MinifyCode, platforms: Array, polyfillModuleNames?: Array, @@ -56,6 +58,7 @@ class Resolver { assetExts: opts.assetExts, cache: opts.cache, extraNodeModules: opts.extraNodeModules, + globalTransformCache: opts.globalTransformCache, ignoreFilePath: function(filepath) { return filepath.indexOf('__tests__') !== -1 || (opts.blacklistRE != null && opts.blacklistRE.test(filepath)); diff --git a/packager/react-packager/src/Server/index.js b/packager/react-packager/src/Server/index.js index a87cb9b34..811b0357a 100644 --- a/packager/react-packager/src/Server/index.js +++ b/packager/react-packager/src/Server/index.js @@ -33,6 +33,7 @@ import type ResolutionResponse from '../node-haste/DependencyGraph/ResolutionRes import type Bundle from '../Bundler/Bundle'; import type {Reporter} from '../lib/reporting'; import type {GetTransformOptions} from '../Bundler'; +import type GlobalTransformCache from '../lib/GlobalTransformCache'; const { createActionStartEntry, @@ -59,6 +60,7 @@ type Options = { cacheVersion?: string, extraNodeModules?: {}, getTransformOptions?: GetTransformOptions, + globalTransformCache: ?GlobalTransformCache, moduleFormat?: string, platforms?: Array, polyfillModuleNames?: Array, @@ -207,6 +209,7 @@ class Server { cacheVersion: options.cacheVersion || '1.0', extraNodeModules: options.extraNodeModules || {}, getTransformOptions: options.getTransformOptions, + globalTransformCache: options.globalTransformCache, moduleFormat: options.moduleFormat != null ? options.moduleFormat : 'haste', platforms: options.platforms || defaults.platforms, polyfillModuleNames: options.polyfillModuleNames || [], @@ -236,6 +239,7 @@ class Server { const bundlerOpts = Object.create(this._opts); bundlerOpts.assetServer = this._assetServer; bundlerOpts.allowBundleUpdates = this._opts.watch; + bundlerOpts.globalTransformCache = options.globalTransformCache; bundlerOpts.watch = this._opts.watch; bundlerOpts.reporter = options.reporter; this._bundler = new Bundler(bundlerOpts); diff --git a/packager/react-packager/src/lib/GlobalTransformCache.js b/packager/react-packager/src/lib/GlobalTransformCache.js index e9df77577..039a6d448 100644 --- a/packager/react-packager/src/lib/GlobalTransformCache.js +++ b/packager/react-packager/src/lib/GlobalTransformCache.js @@ -257,17 +257,20 @@ class TransformProfileSet { } } -/** - * One can enable the global cache by calling configure() from a custom CLI - * script. Eventually we may make it more flexible. - */ class GlobalTransformCache { _fetcher: KeyURIFetcher; _store: ?KeyResultStore; _profileSet: TransformProfileSet; - static _global: ?GlobalTransformCache; + /** + * For using the global cache one needs to have some kind of central key-value + * store that gets prefilled using keyOf() and the transformed results. The + * fetching function should provide a mapping of keys to URIs. The files + * referred by these URIs contains the transform results. Using URIs instead + * of returning the content directly allows for independent and parallel + * fetching of each result, that may be arbitrarily large JSON blobs. + */ constructor( fetchResultURIs: FetchResultURIs, storeResults: ?StoreResults, @@ -343,32 +346,6 @@ class GlobalTransformCache { } } - /** - * For using the global cache one needs to have some kind of central key-value - * store that gets prefilled using keyOf() and the transformed results. The - * fetching function should provide a mapping of keys to URIs. The files - * referred by these URIs contains the transform results. Using URIs instead - * of returning the content directly allows for independent fetching of each - * result. - */ - static configure( - fetchResultURIs: FetchResultURIs, - storeResults: ?StoreResults, - profiles: Iterable, - ) { - GlobalTransformCache._global = new GlobalTransformCache( - fetchResultURIs, - storeResults, - profiles, - ); - } - - static get() { - return GlobalTransformCache._global; - } - } -GlobalTransformCache._global = null; - module.exports = GlobalTransformCache; diff --git a/packager/react-packager/src/node-haste/Module.js b/packager/react-packager/src/node-haste/Module.js index e612ed154..23f7f82dc 100644 --- a/packager/react-packager/src/node-haste/Module.js +++ b/packager/react-packager/src/node-haste/Module.js @@ -11,7 +11,6 @@ 'use strict'; -const GlobalTransformCache = require('../lib/GlobalTransformCache'); const TransformCache = require('../lib/TransformCache'); const crypto = require('crypto'); @@ -24,6 +23,7 @@ const jsonStableStringify = require('json-stable-stringify'); const {join: joinPath, relative: relativePath, extname} = require('path'); import type {TransformedCode, Options as TransformOptions} from '../JSTransformer/worker/worker'; +import type GlobalTransformCache from '../lib/GlobalTransformCache'; import type {SourceMap} from '../lib/SourceMap'; import type {ReadTransformProps} from '../lib/TransformCache'; import type {Reporter} from '../lib/reporting'; @@ -51,14 +51,15 @@ export type Options = { }; export type ConstructorArgs = { + cache: Cache, + depGraphHelpers: DependencyGraphHelpers, + globalTransformCache: ?GlobalTransformCache, file: string, moduleCache: ModuleCache, - cache: Cache, - transformCode: ?TransformCode, - transformCacheKey: ?string, - depGraphHelpers: DependencyGraphHelpers, options: Options, reporter: Reporter, + transformCacheKey: ?string, + transformCode: ?TransformCode, }; class Module { @@ -73,6 +74,7 @@ class Module { _depGraphHelpers: DependencyGraphHelpers; _options: Options; _reporter: Reporter; + _globalCache: ?GlobalTransformCache; _docBlock: Promise<{id?: string, moduleDocBlock: {[key: string]: mixed}}>; _readSourceCodePromise: Promise; @@ -81,14 +83,15 @@ class Module { static _globalCacheRetries: number; constructor({ - file, - moduleCache, cache, - transformCode, - transformCacheKey, depGraphHelpers, - reporter, + file, + globalTransformCache, + moduleCache, options, + reporter, + transformCacheKey, + transformCode, }: ConstructorArgs) { if (!isAbsolutePath(file)) { throw new Error('Expected file to be absolute path but got ' + file); @@ -108,6 +111,7 @@ class Module { this._depGraphHelpers = depGraphHelpers; this._options = options || {}; this._reporter = reporter; + this._globalCache = globalTransformCache; this._readPromises = new Map(); } @@ -263,13 +267,13 @@ class Module { cacheProps: ReadTransformProps, callback: (error: ?Error, result: ?TransformedCode) => void, ) { - const globalCache = GlobalTransformCache.get(); + const {_globalCache} = this; const noMoreRetries = Module._globalCacheRetries <= 0; - if (globalCache == null || noMoreRetries) { + if (_globalCache == null || noMoreRetries) { this._transformCodeForCallback(cacheProps, callback); return; } - globalCache.fetch(cacheProps, (globalCacheError, globalCachedResult) => { + _globalCache.fetch(cacheProps, (globalCacheError, globalCachedResult) => { if (globalCacheError != null && Module._globalCacheRetries > 0) { this._reporter.update({ type: 'global_cache_error', @@ -284,7 +288,7 @@ class Module { } } if (globalCachedResult == null) { - this._transformAndStoreCodeGlobally(cacheProps, globalCache, callback); + this._transformAndStoreCodeGlobally(cacheProps, _globalCache, callback); return; } callback(undefined, globalCachedResult); diff --git a/packager/react-packager/src/node-haste/ModuleCache.js b/packager/react-packager/src/node-haste/ModuleCache.js index 193dac4df..75ad54b26 100644 --- a/packager/react-packager/src/node-haste/ModuleCache.js +++ b/packager/react-packager/src/node-haste/ModuleCache.js @@ -16,13 +16,11 @@ const Module = require('./Module'); const Package = require('./Package'); const Polyfill = require('./Polyfill'); +import type GlobalTransformCache from '../lib/GlobalTransformCache'; import type {Reporter} from '../lib/reporting'; import type Cache from './Cache'; import type DependencyGraphHelpers from './DependencyGraph/DependencyGraphHelpers'; -import type { - TransformCode, - Options as ModuleOptions, -} from './Module'; +import type {TransformCode, Options as ModuleOptions} from './Module'; type GetClosestPackageFn = (filePath: string) => ?string; @@ -32,6 +30,7 @@ class ModuleCache { _cache: Cache; _depGraphHelpers: DependencyGraphHelpers; _getClosestPackage: GetClosestPackageFn; + _globalTransformCache: ?GlobalTransformCache; _moduleCache: {[filePath: string]: Module}; _moduleOptions: ModuleOptions; _packageCache: {[filePath: string]: Package}; @@ -47,22 +46,25 @@ class ModuleCache { depGraphHelpers, extractRequires, getClosestPackage, + globalTransformCache, moduleOptions, + reporter, transformCacheKey, transformCode, - reporter, }: { assetDependencies: Array, cache: Cache, depGraphHelpers: DependencyGraphHelpers, getClosestPackage: GetClosestPackageFn, + globalTransformCache: ?GlobalTransformCache, moduleOptions: ModuleOptions, + reporter: Reporter, transformCacheKey: string, transformCode: TransformCode, - reporter: Reporter, }, platforms: Set) { this._assetDependencies = assetDependencies; this._getClosestPackage = getClosestPackage; + this._globalTransformCache = globalTransformCache; this._cache = cache; this._depGraphHelpers = depGraphHelpers; this._moduleCache = Object.create(null); @@ -78,14 +80,15 @@ class ModuleCache { getModule(filePath: string) { if (!this._moduleCache[filePath]) { this._moduleCache[filePath] = new Module({ - file: filePath, - moduleCache: this, cache: this._cache, - transformCode: this._transformCode, - transformCacheKey: this._transformCacheKey, depGraphHelpers: this._depGraphHelpers, + file: filePath, + globalTransformCache: this._globalTransformCache, + moduleCache: this, options: this._moduleOptions, reporter: this._reporter, + transformCacheKey: this._transformCacheKey, + transformCode: this._transformCode, }); } return this._moduleCache[filePath]; diff --git a/packager/react-packager/src/node-haste/index.js b/packager/react-packager/src/node-haste/index.js index a37f96279..5c64e01c5 100644 --- a/packager/react-packager/src/node-haste/index.js +++ b/packager/react-packager/src/node-haste/index.js @@ -38,6 +38,7 @@ const { } = require('../Logger'); import type {Options as TransformOptions} from '../JSTransformer/worker/worker'; +import type GlobalTransformCache from '../lib/GlobalTransformCache'; import type {Reporter} from '../lib/reporting'; import type { Options as ModuleOptions, @@ -53,6 +54,7 @@ class DependencyGraph { extensions: Array, extraNodeModules: ?Object, forceNodeFilesystemAPI: boolean, + globalTransformCache: ?GlobalTransformCache, ignoreFilePath: (filePath: string) => boolean, maxWorkers: ?number, mocksPattern: mixed, @@ -87,6 +89,7 @@ class DependencyGraph { extensions, extraNodeModules, forceNodeFilesystemAPI, + globalTransformCache, ignoreFilePath, maxWorkers, mocksPattern, @@ -109,6 +112,7 @@ class DependencyGraph { extensions?: ?Array, extraNodeModules: ?Object, forceNodeFilesystemAPI?: boolean, + globalTransformCache: ?GlobalTransformCache, ignoreFilePath: (filePath: string) => boolean, maxWorkers?: ?number, mocksPattern?: mixed, @@ -130,6 +134,7 @@ class DependencyGraph { extensions: extensions || ['js', 'json'], extraNodeModules, forceNodeFilesystemAPI: !!forceNodeFilesystemAPI, + globalTransformCache, ignoreFilePath: ignoreFilePath || (() => {}), maxWorkers, mocksPattern, @@ -186,6 +191,7 @@ class DependencyGraph { this._moduleCache = new ModuleCache({ cache: this._cache, + globalTransformCache: this._opts.globalTransformCache, transformCode: this._opts.transformCode, transformCacheKey: this._opts.transformCacheKey, depGraphHelpers: this._helpers,