mirror of https://github.com/status-im/metro.git
Enable delta bundler on metro-bundler behind a cli argument
Reviewed By: mjesun Differential Revision: D5761110 fbshipit-source-id: 83127f63679caffbc4f335f52f6f5eda398e8c05
This commit is contained in:
parent
7b17ca335d
commit
e18d4e1b89
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const DeltaPatcher = require('./DeltaPatcher');
|
||||||
const DeltaTransformer = require('./DeltaTransformer');
|
const DeltaTransformer = require('./DeltaTransformer');
|
||||||
|
|
||||||
import type Bundler from '../Bundler';
|
import type Bundler from '../Bundler';
|
||||||
|
@ -42,6 +43,7 @@ class DeltaBundler {
|
||||||
_bundler: Bundler;
|
_bundler: Bundler;
|
||||||
_options: MainOptions;
|
_options: MainOptions;
|
||||||
_deltaTransformers: Map<string, DeltaTransformer> = new Map();
|
_deltaTransformers: Map<string, DeltaTransformer> = new Map();
|
||||||
|
_deltaPatchers: Map<string, DeltaPatcher> = new Map();
|
||||||
_currentId: number = 0;
|
_currentId: number = 0;
|
||||||
|
|
||||||
constructor(bundler: Bundler, options: MainOptions) {
|
constructor(bundler: Bundler, options: MainOptions) {
|
||||||
|
@ -81,6 +83,20 @@ class DeltaBundler {
|
||||||
id: bundleId,
|
id: bundleId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async buildFullBundle(options: Options): Promise<string> {
|
||||||
|
const deltaBundle = await this.build(options);
|
||||||
|
|
||||||
|
let deltaPatcher = this._deltaPatchers.get(deltaBundle.id);
|
||||||
|
|
||||||
|
if (!deltaPatcher) {
|
||||||
|
deltaPatcher = new DeltaPatcher();
|
||||||
|
|
||||||
|
this._deltaPatchers.set(deltaBundle.id, deltaPatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
return deltaPatcher.applyDelta(deltaBundle).stringify();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = DeltaBundler;
|
module.exports = DeltaBundler;
|
||||||
|
|
|
@ -14,8 +14,10 @@
|
||||||
|
|
||||||
const AssetServer = require('../AssetServer');
|
const AssetServer = require('../AssetServer');
|
||||||
const Bundler = require('../Bundler');
|
const Bundler = require('../Bundler');
|
||||||
|
const DeltaBundler = require('../DeltaBundler');
|
||||||
const MultipartResponse = require('./MultipartResponse');
|
const MultipartResponse = require('./MultipartResponse');
|
||||||
|
|
||||||
|
const crypto = require('crypto');
|
||||||
const debug = require('debug')('Metro:Server');
|
const debug = require('debug')('Metro:Server');
|
||||||
const defaults = require('../defaults');
|
const defaults = require('../defaults');
|
||||||
const emptyFunction = require('fbjs/lib/emptyFunction');
|
const emptyFunction = require('fbjs/lib/emptyFunction');
|
||||||
|
@ -93,6 +95,7 @@ export type Options = {|
|
||||||
+sourceExts: ?Array<string>,
|
+sourceExts: ?Array<string>,
|
||||||
+transformCache: TransformCache,
|
+transformCache: TransformCache,
|
||||||
transformModulePath?: string,
|
transformModulePath?: string,
|
||||||
|
useDeltaBundler: boolean,
|
||||||
watch?: boolean,
|
watch?: boolean,
|
||||||
workerPath: ?string,
|
workerPath: ?string,
|
||||||
|};
|
|};
|
||||||
|
@ -182,6 +185,7 @@ class Server {
|
||||||
_symbolicateInWorker: Symbolicate;
|
_symbolicateInWorker: Symbolicate;
|
||||||
_platforms: Set<string>;
|
_platforms: Set<string>;
|
||||||
_nextBundleBuildID: number;
|
_nextBundleBuildID: number;
|
||||||
|
_deltaBundler: DeltaBundler;
|
||||||
|
|
||||||
constructor(options: Options) {
|
constructor(options: Options) {
|
||||||
const reporter =
|
const reporter =
|
||||||
|
@ -218,6 +222,7 @@ class Server {
|
||||||
transformCache: options.transformCache,
|
transformCache: options.transformCache,
|
||||||
transformModulePath:
|
transformModulePath:
|
||||||
options.transformModulePath || defaults.transformModulePath,
|
options.transformModulePath || defaults.transformModulePath,
|
||||||
|
useDeltaBundler: options.useDeltaBundler,
|
||||||
watch: options.watch || false,
|
watch: options.watch || false,
|
||||||
workerPath: options.workerPath,
|
workerPath: options.workerPath,
|
||||||
};
|
};
|
||||||
|
@ -285,6 +290,13 @@ class Server {
|
||||||
|
|
||||||
this._symbolicateInWorker = symbolicate.createWorker();
|
this._symbolicateInWorker = symbolicate.createWorker();
|
||||||
this._nextBundleBuildID = 1;
|
this._nextBundleBuildID = 1;
|
||||||
|
|
||||||
|
if (this._opts.useDeltaBundler) {
|
||||||
|
this._deltaBundler = new DeltaBundler(this._bundler, {
|
||||||
|
getPolyfills: this._opts.getPolyfills,
|
||||||
|
polyfillModuleNames: this._opts.polyfillModuleNames,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end(): mixed {
|
end(): mixed {
|
||||||
|
@ -735,7 +747,7 @@ class Server {
|
||||||
return this._reportBundlePromise(buildID, options, bundleFromScratch());
|
return this._reportBundlePromise(buildID, options, bundleFromScratch());
|
||||||
}
|
}
|
||||||
|
|
||||||
processRequest(
|
async processRequest(
|
||||||
req: IncomingMessage,
|
req: IncomingMessage,
|
||||||
res: ServerResponse,
|
res: ServerResponse,
|
||||||
next?: () => mixed,
|
next?: () => mixed,
|
||||||
|
@ -774,6 +786,11 @@ class Server {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._opts.useDeltaBundler && requestType === 'bundle') {
|
||||||
|
await this._processRequestUsingDeltaBundler(req, res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const options = this._getOptionsFromUrl(req.url);
|
const options = this._getOptionsFromUrl(req.url);
|
||||||
const requestingBundleLogEntry = log(
|
const requestingBundleLogEntry = log(
|
||||||
createActionStartEntry({
|
createActionStartEntry({
|
||||||
|
@ -859,6 +876,67 @@ class Server {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async _processRequestUsingDeltaBundler(
|
||||||
|
req: IncomingMessage,
|
||||||
|
res: ServerResponse,
|
||||||
|
) {
|
||||||
|
const options = this._getOptionsFromUrl(req.url);
|
||||||
|
const requestingBundleLogEntry = log(
|
||||||
|
createActionStartEntry({
|
||||||
|
action_name: 'Requesting bundle',
|
||||||
|
bundle_url: req.url,
|
||||||
|
entry_point: options.entryFile,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const buildID = this.getNewBuildID();
|
||||||
|
|
||||||
|
if (!this._opts.silent) {
|
||||||
|
options.onProgress = (transformedFileCount, totalFileCount) => {
|
||||||
|
this._reporter.update({
|
||||||
|
buildID,
|
||||||
|
type: 'bundle_transform_progressed',
|
||||||
|
transformedFileCount,
|
||||||
|
totalFileCount,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
this._reporter.update({
|
||||||
|
buildID,
|
||||||
|
bundleOptions: options,
|
||||||
|
type: 'bundle_build_started',
|
||||||
|
});
|
||||||
|
|
||||||
|
const bundle = await this._deltaBundler.buildFullBundle({
|
||||||
|
...options,
|
||||||
|
deltaBundleId: this.optionsHash(options),
|
||||||
|
});
|
||||||
|
|
||||||
|
const etag = crypto.createHash('md5').update(bundle).digest('hex');
|
||||||
|
|
||||||
|
if (req.headers['if-none-match'] === etag) {
|
||||||
|
debug('Responding with 304');
|
||||||
|
res.writeHead(304);
|
||||||
|
res.end();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setHeader('Content-Type', 'application/javascript');
|
||||||
|
res.setHeader('ETag', etag);
|
||||||
|
res.setHeader('Content-Length', String(Buffer.byteLength(bundle)));
|
||||||
|
res.end(bundle);
|
||||||
|
|
||||||
|
this._reporter.update({
|
||||||
|
buildID,
|
||||||
|
type: 'bundle_build_done',
|
||||||
|
});
|
||||||
|
|
||||||
|
debug('Finished response');
|
||||||
|
log(createActionEndEntry(requestingBundleLogEntry));
|
||||||
|
}
|
||||||
|
|
||||||
_symbolicate(req: IncomingMessage, res: ServerResponse) {
|
_symbolicate(req: IncomingMessage, res: ServerResponse) {
|
||||||
const symbolicatingLogEntry = log(createActionStartEntry('Symbolicating'));
|
const symbolicatingLogEntry = log(createActionStartEntry('Symbolicating'));
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,7 @@ function toServerOptions(options: Options): ServerOptions {
|
||||||
sourceExts: options.sourceExts,
|
sourceExts: options.sourceExts,
|
||||||
transformCache: options.transformCache || TransformCaching.useTempDir(),
|
transformCache: options.transformCache || TransformCaching.useTempDir(),
|
||||||
transformModulePath: options.transformModulePath,
|
transformModulePath: options.transformModulePath,
|
||||||
|
useDeltaBundler: options.useDeltaBundler,
|
||||||
watch: typeof options.watch === 'boolean' ? options.watch : !!options.nonPersistent,
|
watch: typeof options.watch === 'boolean' ? options.watch : !!options.nonPersistent,
|
||||||
workerPath: options.workerPath,
|
workerPath: options.workerPath,
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue