From 87e808693724cd5ffe04a0875ef3f1913d1c7d4a Mon Sep 17 00:00:00 2001 From: David Aurelio Date: Fri, 8 Jan 2016 08:34:52 -0800 Subject: [PATCH] Require transform file eagerly in transform worker Summary: One consequence we didn't predict after introducing the Internal Transform Pipeline, was that when the workers would get started, we won't require the external transformer the user specified up until the first time each worker received a job. There're 2 visible consequences of this: (1) the transform progress bar seems to get stuck for about 5 seconds the first time the packager receives a request and (2) the first N (# of cores) HMR requests take way longer (about 4 seconds with FB's transformer instead of << 1 second) as we need to require lots of modules. This diff creates a temporary file for the js transformer workers that requires the user-specified transform file eagerly. That makes sure workers have imported babel and the transforms before receiving the first request. There are better ways to do this, like adding an `init()` method to the workers and call that eagerly. I will follow with another diff doing that. public Reviewed By: javache Differential Revision: D2812153 fb-gh-sync-id: 15be316b792d1acd878ed9303bea398aa0b52e1d --- .../JSTransformer/__tests__/Transformer-test.js | 1 + react-packager/src/JSTransformer/index.js | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/react-packager/src/JSTransformer/__tests__/Transformer-test.js b/react-packager/src/JSTransformer/__tests__/Transformer-test.js index 83275f14..7e129768 100644 --- a/react-packager/src/JSTransformer/__tests__/Transformer-test.js +++ b/react-packager/src/JSTransformer/__tests__/Transformer-test.js @@ -13,6 +13,7 @@ jest .dontMock('../'); jest.mock('fs'); +jest.setMock('temp', {path: () => '/arbitrary/path'}); var Cache = require('../../DependencyResolver/Cache'); var Transformer = require('../'); diff --git a/react-packager/src/JSTransformer/index.js b/react-packager/src/JSTransformer/index.js index 2688e14c..6cba12e5 100644 --- a/react-packager/src/JSTransformer/index.js +++ b/react-packager/src/JSTransformer/index.js @@ -12,6 +12,7 @@ const ModuleTransport = require('../lib/ModuleTransport'); const Promise = require('promise'); const declareOpts = require('../lib/declareOpts'); const fs = require('fs'); +const temp = require('temp'); const util = require('util'); const workerFarm = require('worker-farm'); const debug = require('debug')('ReactNativePackager:JStransformer'); @@ -63,13 +64,22 @@ class Transformer { this._transformModulePath = opts.transformModulePath; if (opts.transformModulePath != null) { + this._workerWrapperPath = temp.path(); + fs.writeFileSync( + this._workerWrapperPath, + ` + module.exports = require(${JSON.stringify(require.resolve('./worker'))}); + require(${JSON.stringify(String(opts.transformModulePath))}); + ` + ); + this._workers = workerFarm({ autoStart: true, maxConcurrentCallsPerWorker: 1, maxCallsPerWorker: MAX_CALLS_PER_WORKER, maxCallTime: opts.transformTimeoutInterval, maxRetries: MAX_RETRIES, - }, require.resolve('./worker')); + }, this._workerWrapperPath); this._transform = Promise.denodeify(this._workers); } @@ -77,6 +87,9 @@ class Transformer { kill() { this._workers && workerFarm.end(this._workers); + if (typeof this._workerWrapperPath === 'string') { + fs.unlink(this._workerWrapperPath, () => {}); // we don't care about potential errors here + } } invalidateFile(filePath) {