From 324493edae0094fb078d8fecf570385df32e576b 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 --- package.json | 4 ++-- .../JSTransformer/__tests__/Transformer-test.js | 1 + .../react-packager/src/JSTransformer/index.js | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index cd893d1fa..a52208af4 100644 --- a/package.json +++ b/package.json @@ -167,6 +167,7 @@ "semver": "^5.0.3", "source-map": "^0.4.4", "stacktrace-parser": "^0.1.3", + "temp": "0.8.3", "uglify-js": "^2.4.24", "underscore": "^1.8.3", "wordwrap": "^1.0.0", @@ -181,7 +182,6 @@ "babel-eslint": "4.1.4", "eslint": "1.3.1", "eslint-plugin-react": "3.3.1", - "portfinder": "0.4.0", - "temp": "0.8.3" + "portfinder": "0.4.0" } } diff --git a/packager/react-packager/src/JSTransformer/__tests__/Transformer-test.js b/packager/react-packager/src/JSTransformer/__tests__/Transformer-test.js index 83275f142..7e1297689 100644 --- a/packager/react-packager/src/JSTransformer/__tests__/Transformer-test.js +++ b/packager/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/packager/react-packager/src/JSTransformer/index.js b/packager/react-packager/src/JSTransformer/index.js index 2688e14cf..6cba12e51 100644 --- a/packager/react-packager/src/JSTransformer/index.js +++ b/packager/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) {