mirror of https://github.com/status-im/metro.git
Move progress bar from Bundler to Server
Summary: Context: I'm trying to add support for sending packager progress events to the client that is downloading the bundle over HTTP multipart response. In order to do that I need the server to know about these events. Currently the bundler doesn't expose any hooks for monitoring the progress, so this diff introduces `onProgress` option for that. Reviewed By: davidaurelio Differential Revision: D3926806 fbshipit-source-id: b7d9c649df4f94ddf5082791209844610650325e
This commit is contained in:
parent
ecd933e73d
commit
d9797e2de7
|
@ -8,11 +8,11 @@
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const Promise = require('promise');
|
||||||
|
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const Promise = require('promise');
|
|
||||||
const ProgressBar = require('progress');
|
|
||||||
const Cache = require('../node-haste').Cache;
|
const Cache = require('../node-haste').Cache;
|
||||||
const Transformer = require('../JSTransformer');
|
const Transformer = require('../JSTransformer');
|
||||||
const Resolver = require('../Resolver');
|
const Resolver = require('../Resolver');
|
||||||
|
@ -85,10 +85,6 @@ const validateOpts = declareOpts({
|
||||||
type: 'number',
|
type: 'number',
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
silent: {
|
|
||||||
type: 'boolean',
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
allowBundleUpdates: {
|
allowBundleUpdates: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
default: false,
|
default: false,
|
||||||
|
@ -260,6 +256,7 @@ class Bundler {
|
||||||
isolateModuleIDs,
|
isolateModuleIDs,
|
||||||
generateSourceMaps,
|
generateSourceMaps,
|
||||||
assetPlugins,
|
assetPlugins,
|
||||||
|
onProgress,
|
||||||
}) {
|
}) {
|
||||||
const onResolutionResponse = response => {
|
const onResolutionResponse = response => {
|
||||||
bundle.setMainModuleId(response.getModuleId(getMainModule(response)));
|
bundle.setMainModuleId(response.getModuleId(getMainModule(response)));
|
||||||
|
@ -306,6 +303,7 @@ class Bundler {
|
||||||
isolateModuleIDs,
|
isolateModuleIDs,
|
||||||
generateSourceMaps,
|
generateSourceMaps,
|
||||||
assetPlugins,
|
assetPlugins,
|
||||||
|
onProgress,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,6 +362,7 @@ class Bundler {
|
||||||
onResolutionResponse = noop,
|
onResolutionResponse = noop,
|
||||||
onModuleTransformed = noop,
|
onModuleTransformed = noop,
|
||||||
finalizeBundle = noop,
|
finalizeBundle = noop,
|
||||||
|
onProgress = noop,
|
||||||
}) {
|
}) {
|
||||||
const findEventId = Activity.startEvent(
|
const findEventId = Activity.startEvent(
|
||||||
'Transforming modules',
|
'Transforming modules',
|
||||||
|
@ -377,17 +376,6 @@ class Bundler {
|
||||||
const modulesByName = Object.create(null);
|
const modulesByName = Object.create(null);
|
||||||
|
|
||||||
if (!resolutionResponse) {
|
if (!resolutionResponse) {
|
||||||
let onProgress = noop;
|
|
||||||
if (process.stdout.isTTY && !this._opts.silent) {
|
|
||||||
const bar = new ProgressBar('transformed :current/:total (:percent)', {
|
|
||||||
complete: '=',
|
|
||||||
incomplete: ' ',
|
|
||||||
width: 40,
|
|
||||||
total: 1,
|
|
||||||
});
|
|
||||||
onProgress = debouncedTick(bar);
|
|
||||||
}
|
|
||||||
|
|
||||||
resolutionResponse = this.getDependencies({
|
resolutionResponse = this.getDependencies({
|
||||||
entryFile,
|
entryFile,
|
||||||
dev,
|
dev,
|
||||||
|
@ -775,25 +763,6 @@ function getMainModule({dependencies, numPrependedDependencies = 0}) {
|
||||||
return dependencies[numPrependedDependencies];
|
return dependencies[numPrependedDependencies];
|
||||||
}
|
}
|
||||||
|
|
||||||
function debouncedTick(progressBar) {
|
|
||||||
let n = 0;
|
|
||||||
let start, total;
|
|
||||||
|
|
||||||
return (_, t) => {
|
|
||||||
total = t;
|
|
||||||
n += 1;
|
|
||||||
if (start) {
|
|
||||||
if (progressBar.curr + n >= total || Date.now() - start > 200) {
|
|
||||||
progressBar.total = total;
|
|
||||||
progressBar.tick(n);
|
|
||||||
start = n = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
start = Date.now();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterObject(object, blacklist) {
|
function filterObject(object, blacklist) {
|
||||||
const copied = Object.assign({}, object);
|
const copied = Object.assign({}, object);
|
||||||
for (const key of blacklist) {
|
for (const key of blacklist) {
|
||||||
|
|
|
@ -13,6 +13,7 @@ const AssetServer = require('../AssetServer');
|
||||||
const FileWatcher = require('../node-haste').FileWatcher;
|
const FileWatcher = require('../node-haste').FileWatcher;
|
||||||
const getPlatformExtension = require('../node-haste').getPlatformExtension;
|
const getPlatformExtension = require('../node-haste').getPlatformExtension;
|
||||||
const Bundler = require('../Bundler');
|
const Bundler = require('../Bundler');
|
||||||
|
const ProgressBar = require('progress');
|
||||||
const Promise = require('promise');
|
const Promise = require('promise');
|
||||||
const SourceMapConsumer = require('source-map').SourceMapConsumer;
|
const SourceMapConsumer = require('source-map').SourceMapConsumer;
|
||||||
|
|
||||||
|
@ -158,6 +159,9 @@ const bundleOpts = declareOpts({
|
||||||
type: 'array',
|
type: 'array',
|
||||||
default: [],
|
default: [],
|
||||||
},
|
},
|
||||||
|
onProgress: {
|
||||||
|
type: 'function',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const dependencyOpts = declareOpts({
|
const dependencyOpts = declareOpts({
|
||||||
|
@ -192,7 +196,7 @@ const NODE_MODULES = `${path.sep}node_modules${path.sep}`;
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
const opts = validateOpts(options);
|
const opts = this._opts = validateOpts(options);
|
||||||
|
|
||||||
this._projectRoots = opts.projectRoots;
|
this._projectRoots = opts.projectRoots;
|
||||||
this._bundles = Object.create(null);
|
this._bundles = Object.create(null);
|
||||||
|
@ -511,8 +515,13 @@ class Server {
|
||||||
).done(() => Activity.endEvent(assetEvent));
|
).done(() => Activity.endEvent(assetEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
optionsHash(options) {
|
||||||
|
// onProgress is a function, can't be serialized
|
||||||
|
return JSON.stringify(Object.assign({}, options, { onProgress: null }));
|
||||||
|
}
|
||||||
|
|
||||||
_useCachedOrUpdateOrCreateBundle(options) {
|
_useCachedOrUpdateOrCreateBundle(options) {
|
||||||
const optionsJson = JSON.stringify(options);
|
const optionsJson = this.optionsHash(options);
|
||||||
const bundleFromScratch = () => {
|
const bundleFromScratch = () => {
|
||||||
const building = this.buildBundle(options);
|
const building = this.buildBundle(options);
|
||||||
this._bundles[optionsJson] = building;
|
this._bundles[optionsJson] = building;
|
||||||
|
@ -647,6 +656,16 @@ class Server {
|
||||||
details: req.url,
|
details: req.url,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (process.stdout.isTTY && !this._opts.silent) {
|
||||||
|
const bar = new ProgressBar('transformed :current/:total (:percent)', {
|
||||||
|
complete: '=',
|
||||||
|
incomplete: ' ',
|
||||||
|
width: 40,
|
||||||
|
total: 1,
|
||||||
|
});
|
||||||
|
options.onProgress = debouncedTick(bar);
|
||||||
|
}
|
||||||
debug('Getting bundle for request');
|
debug('Getting bundle for request');
|
||||||
const building = this._useCachedOrUpdateOrCreateBundle(options);
|
const building = this._useCachedOrUpdateOrCreateBundle(options);
|
||||||
building.then(
|
building.then(
|
||||||
|
@ -691,7 +710,7 @@ class Server {
|
||||||
Activity.endEvent(startReqEventId);
|
Activity.endEvent(startReqEventId);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error => this._handleError(res, JSON.stringify(options), error)
|
error => this._handleError(res, this.optionsHash(options), error)
|
||||||
).catch(error => {
|
).catch(error => {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
throw error;
|
throw error;
|
||||||
|
@ -867,4 +886,23 @@ function contentsEqual(array, set) {
|
||||||
return array.length === set.size && array.every(set.has, set);
|
return array.length === set.size && array.every(set.has, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function debouncedTick(progressBar) {
|
||||||
|
let n = 0;
|
||||||
|
let start, total;
|
||||||
|
|
||||||
|
return (_, t) => {
|
||||||
|
total = t;
|
||||||
|
n += 1;
|
||||||
|
if (start) {
|
||||||
|
if (progressBar.curr + n >= total || Date.now() - start > 200) {
|
||||||
|
progressBar.total = total;
|
||||||
|
progressBar.tick(n);
|
||||||
|
start = n = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
start = Date.now();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = Server;
|
module.exports = Server;
|
||||||
|
|
Loading…
Reference in New Issue