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
|
* 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
|
* 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.
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||||||
|
*
|
||||||
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const Logger = require('../Logger');
|
const Logger = require('../Logger');
|
||||||
|
@ -17,6 +20,8 @@ const util = require('util');
|
||||||
const workerFarm = require('worker-farm');
|
const workerFarm = require('worker-farm');
|
||||||
const debug = require('debug')('ReactNativePackager:JStransformer');
|
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
|
// 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.
|
// 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.
|
// 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) => {
|
const maxConcurrentWorkers = ((cores, override) => {
|
||||||
if (override) {
|
if (override) {
|
||||||
return Math.min(cores, 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 Math.floor(3 / 8 * cores + 3); // between cores *.75 and cores / 2
|
||||||
}
|
}
|
||||||
return 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) {
|
function makeFarm(worker, methods, timeout) {
|
||||||
return workerFarm(
|
return workerFarm(
|
||||||
|
@ -79,7 +91,28 @@ function makeFarm(worker, methods, timeout) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Transformer {
|
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 opts = this._opts = validateOpts(options);
|
||||||
|
|
||||||
const {transformModulePath} = opts;
|
const {transformModulePath} = opts;
|
||||||
|
@ -88,6 +121,8 @@ class Transformer {
|
||||||
this._workers =
|
this._workers =
|
||||||
makeFarm(opts.worker, opts.methods, opts.transformTimeoutInterval);
|
makeFarm(opts.worker, opts.methods, opts.transformTimeoutInterval);
|
||||||
opts.methods.forEach(name => {
|
opts.methods.forEach(name => {
|
||||||
|
/* $FlowFixMe: assigning the class object fields directly is
|
||||||
|
* questionable, because it's prone to conflicts. */
|
||||||
this[name] = this._workers[name];
|
this[name] = this._workers[name];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -108,12 +143,13 @@ class Transformer {
|
||||||
this._workers && workerFarm.end(this._workers);
|
this._workers && workerFarm.end(this._workers);
|
||||||
}
|
}
|
||||||
|
|
||||||
transformFile(fileName, code, options) {
|
transformFile(fileName: string, code: string, options: TransformOptions) {
|
||||||
if (!this._transform) {
|
if (!this._transform) {
|
||||||
return Promise.reject(new Error('No transform module'));
|
return Promise.reject(new Error('No transform module'));
|
||||||
}
|
}
|
||||||
debug('transforming file', fileName);
|
debug('transforming file', fileName);
|
||||||
return this
|
return this
|
||||||
|
/* $FlowFixMe: _transformModulePath may be empty, see constructor */
|
||||||
._transform(this._transformModulePath, fileName, code, options)
|
._transform(this._transformModulePath, fileName, code, options)
|
||||||
.then(data => {
|
.then(data => {
|
||||||
Logger.log(data.transformFileStartLogEntry);
|
Logger.log(data.transformFileStartLogEntry);
|
||||||
|
@ -128,13 +164,16 @@ class Transformer {
|
||||||
`${this._opts.transformTimeoutInterval / 1000} seconds.\n` +
|
`${this._opts.transformTimeoutInterval / 1000} seconds.\n` +
|
||||||
'You can adjust timeout via the \'transformTimeoutInterval\' option'
|
'You can adjust timeout via the \'transformTimeoutInterval\' option'
|
||||||
);
|
);
|
||||||
|
/* $FlowFixMe: monkey-patch Error */
|
||||||
timeoutErr.type = 'TimeoutError';
|
timeoutErr.type = 'TimeoutError';
|
||||||
throw timeoutErr;
|
throw timeoutErr;
|
||||||
} else if (error.type === 'ProcessTerminatedError') {
|
} else if (error.type === 'ProcessTerminatedError') {
|
||||||
const uncaughtError = new Error(
|
const uncaughtError = new Error(
|
||||||
'Uncaught error in the transformer worker: ' +
|
'Uncaught error in the transformer worker: ' +
|
||||||
|
/* $FlowFixMe: _transformModulePath may be empty, see constructor */
|
||||||
this._opts.transformModulePath
|
this._opts.transformModulePath
|
||||||
);
|
);
|
||||||
|
/* $FlowFixMe: monkey-patch Error */
|
||||||
uncaughtError.type = 'ProcessTerminatedError';
|
uncaughtError.type = 'ProcessTerminatedError';
|
||||||
throw uncaughtError;
|
throw uncaughtError;
|
||||||
}
|
}
|
||||||
|
@ -142,6 +181,8 @@ class Transformer {
|
||||||
throw formatError(error, fileName);
|
throw formatError(error, fileName);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TransformError;
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = Transformer;
|
module.exports = Transformer;
|
||||||
|
|
|
@ -16,6 +16,8 @@ const extractDependencies = require('./extract-dependencies');
|
||||||
const inline = require('./inline');
|
const inline = require('./inline');
|
||||||
const minify = require('./minify');
|
const minify = require('./minify');
|
||||||
|
|
||||||
|
import type {LogEntry} from '../../Logger/Types';
|
||||||
|
|
||||||
function makeTransformParams(filename, sourceCode, options) {
|
function makeTransformParams(filename, sourceCode, options) {
|
||||||
if (filename.endsWith('.json')) {
|
if (filename.endsWith('.json')) {
|
||||||
sourceCode = 'module.exports=' + sourceCode;
|
sourceCode = 'module.exports=' + sourceCode;
|
||||||
|
@ -36,15 +38,17 @@ type Transform = (params: {
|
||||||
options: ?{},
|
options: ?{},
|
||||||
}) => mixed;
|
}) => mixed;
|
||||||
|
|
||||||
type Options = {transform?: {}};
|
export type Options = {transform?: {}};
|
||||||
|
|
||||||
|
export type Data = {
|
||||||
|
result: TransformedCode,
|
||||||
|
transformFileStartLogEntry: LogEntry,
|
||||||
|
transformFileEndLogEntry: LogEntry,
|
||||||
|
};
|
||||||
|
|
||||||
type Callback = (
|
type Callback = (
|
||||||
error: ?Error,
|
error: ?Error,
|
||||||
data: ?{
|
data: ?Data,
|
||||||
result: TransformedCode,
|
|
||||||
transformFileStartLogEntry: {},
|
|
||||||
transformFileEndLogEntry: {},
|
|
||||||
},
|
|
||||||
) => mixed;
|
) => mixed;
|
||||||
|
|
||||||
function transformCode(
|
function transformCode(
|
||||||
|
|
Loading…
Reference in New Issue