mirror of https://github.com/status-im/metro.git
packager: JSTransformer/index.js: @flow
Reviewed By: cpojer Differential Revision: D4167006 fbshipit-source-id: db0deb2262fe2c53735cb46d9de6e6da1b375180
This commit is contained in:
parent
ece4a18d7c
commit
77d1ca470d
|
@ -5,7 +5,10 @@
|
|||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const Logger = require('../Logger');
|
||||
|
@ -17,6 +20,8 @@ const util = require('util');
|
|||
const workerFarm = require('worker-farm');
|
||||
const debug = require('debug')('ReactNativePackager:JStransformer');
|
||||
|
||||
import type {Data as TransformData, Options as TransformOptions} from './worker/worker';
|
||||
|
||||
// Avoid memory leaks caused in workers. This number seems to be a good enough number
|
||||
// to avoid any memory leak while not slowing down initial builds.
|
||||
// TODO(amasad): Once we get bundle splitting, we can drive this down a bit more.
|
||||
|
@ -46,6 +51,13 @@ const validateOpts = declareOpts({
|
|||
},
|
||||
});
|
||||
|
||||
type Options = {
|
||||
transformModulePath?: ?string,
|
||||
transformTimeoutInterval?: ?number,
|
||||
worker?: ?string,
|
||||
methods?: ?Array<string>,
|
||||
};
|
||||
|
||||
const maxConcurrentWorkers = ((cores, override) => {
|
||||
if (override) {
|
||||
return Math.min(cores, override);
|
||||
|
@ -61,7 +73,7 @@ const maxConcurrentWorkers = ((cores, override) => {
|
|||
return Math.floor(3 / 8 * cores + 3); // between cores *.75 and cores / 2
|
||||
}
|
||||
return cores / 2;
|
||||
})(os.cpus().length, process.env.REACT_NATIVE_MAX_WORKERS);
|
||||
})(os.cpus().length, parseInt(process.env.REACT_NATIVE_MAX_WORKERS, 10));
|
||||
|
||||
function makeFarm(worker, methods, timeout) {
|
||||
return workerFarm(
|
||||
|
@ -79,7 +91,28 @@ function makeFarm(worker, methods, timeout) {
|
|||
}
|
||||
|
||||
class Transformer {
|
||||
constructor(options) {
|
||||
|
||||
_opts: {
|
||||
transformModulePath?: ?string,
|
||||
transformTimeoutInterval: number,
|
||||
worker: ?string,
|
||||
methods: Array<string>,
|
||||
};
|
||||
_workers: {[name: string]: mixed};
|
||||
_transformModulePath: ?string;
|
||||
_transform: (
|
||||
transform: string,
|
||||
filename: string,
|
||||
sourceCode: string,
|
||||
options: ?TransformOptions,
|
||||
) => Promise<TransformData>;
|
||||
minify: (
|
||||
filename: string,
|
||||
code: string,
|
||||
sourceMap: string,
|
||||
) => Promise<mixed>;
|
||||
|
||||
constructor(options: Options) {
|
||||
const opts = this._opts = validateOpts(options);
|
||||
|
||||
const {transformModulePath} = opts;
|
||||
|
@ -88,6 +121,8 @@ class Transformer {
|
|||
this._workers =
|
||||
makeFarm(opts.worker, opts.methods, opts.transformTimeoutInterval);
|
||||
opts.methods.forEach(name => {
|
||||
/* $FlowFixMe: assigning the class object fields directly is
|
||||
* questionable, because it's prone to conflicts. */
|
||||
this[name] = this._workers[name];
|
||||
});
|
||||
}
|
||||
|
@ -108,12 +143,13 @@ class Transformer {
|
|||
this._workers && workerFarm.end(this._workers);
|
||||
}
|
||||
|
||||
transformFile(fileName, code, options) {
|
||||
transformFile(fileName: string, code: string, options: TransformOptions) {
|
||||
if (!this._transform) {
|
||||
return Promise.reject(new Error('No transform module'));
|
||||
}
|
||||
debug('transforming file', fileName);
|
||||
return this
|
||||
/* $FlowFixMe: _transformModulePath may be empty, see constructor */
|
||||
._transform(this._transformModulePath, fileName, code, options)
|
||||
.then(data => {
|
||||
Logger.log(data.transformFileStartLogEntry);
|
||||
|
@ -128,13 +164,16 @@ class Transformer {
|
|||
`${this._opts.transformTimeoutInterval / 1000} seconds.\n` +
|
||||
'You can adjust timeout via the \'transformTimeoutInterval\' option'
|
||||
);
|
||||
/* $FlowFixMe: monkey-patch Error */
|
||||
timeoutErr.type = 'TimeoutError';
|
||||
throw timeoutErr;
|
||||
} else if (error.type === 'ProcessTerminatedError') {
|
||||
const uncaughtError = new Error(
|
||||
'Uncaught error in the transformer worker: ' +
|
||||
/* $FlowFixMe: _transformModulePath may be empty, see constructor */
|
||||
this._opts.transformModulePath
|
||||
);
|
||||
/* $FlowFixMe: monkey-patch Error */
|
||||
uncaughtError.type = 'ProcessTerminatedError';
|
||||
throw uncaughtError;
|
||||
}
|
||||
|
@ -142,6 +181,8 @@ class Transformer {
|
|||
throw formatError(error, fileName);
|
||||
});
|
||||
}
|
||||
|
||||
static TransformError;
|
||||
}
|
||||
|
||||
module.exports = Transformer;
|
||||
|
|
|
@ -16,6 +16,8 @@ const extractDependencies = require('./extract-dependencies');
|
|||
const inline = require('./inline');
|
||||
const minify = require('./minify');
|
||||
|
||||
import type {LogEntry} from '../../Logger/Types';
|
||||
|
||||
function makeTransformParams(filename, sourceCode, options) {
|
||||
if (filename.endsWith('.json')) {
|
||||
sourceCode = 'module.exports=' + sourceCode;
|
||||
|
@ -36,15 +38,17 @@ type Transform = (params: {
|
|||
options: ?{},
|
||||
}) => mixed;
|
||||
|
||||
type Options = {transform?: {}};
|
||||
export type Options = {transform?: {}};
|
||||
|
||||
export type Data = {
|
||||
result: TransformedCode,
|
||||
transformFileStartLogEntry: LogEntry,
|
||||
transformFileEndLogEntry: LogEntry,
|
||||
};
|
||||
|
||||
type Callback = (
|
||||
error: ?Error,
|
||||
data: ?{
|
||||
result: TransformedCode,
|
||||
transformFileStartLogEntry: {},
|
||||
transformFileEndLogEntry: {},
|
||||
},
|
||||
data: ?Data,
|
||||
) => mixed;
|
||||
|
||||
function transformCode(
|
||||
|
|
Loading…
Reference in New Issue