From 6d46078e74ae9a43aa90bed46dbd6610e2696cd0 Mon Sep 17 00:00:00 2001 From: Rob Hogan Date: Tue, 4 Jul 2023 08:02:37 -0700 Subject: [PATCH] Fix mismatched `metro-transform-worker` version - use absolute worker paths Summary: Issues such as https://github.com/facebook/metro/issues/1017 (and similar previously) have had users running into broken setups due to "multiple versions of Metro" installed. Ideally, multiple Metros wouldn't be a problem. Metro packages already specify explicit, pinned dependencies on each other, and well-behaved package resolutions should stay within those disconnected graphs of Metro versions. In particular `metro` already specifies its dependency on `metro-transform-worker`, so it wasn't obvious how we were "escaping" from the correct `metro` and ending up inside the wrong `metro-transform-worker` here. I was able to reproduce https://github.com/facebook/metro/issues/1017 with Berry and debug it. It turns out that the problem is the use of the (undocumented) `transformer.workerPath` option, which defaults to `'metro/src/DeltaBundler/Worker'`. We pass that to `jest-worker`, which forks a child process `jest-worker/build/workers/processChild`, which resolves the given path *relative to `jest-worker`* - so usually resolves the *hoisted* `metro`, whatever that happens to be. This fixes the issue by resolving the path from the parent process, within `metro`, and passing an absolute path to `jest-worker`. Changelog: ``` - **[Fix]**: Incorrect worker resolution when multiple `metro` versions are installed. ``` Reviewed By: huntie Differential Revision: D47209874 fbshipit-source-id: 5aa101852e9d33af6f41c118252d9874701a01be --- packages/metro/src/DeltaBundler/WorkerFarm.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/metro/src/DeltaBundler/WorkerFarm.js b/packages/metro/src/DeltaBundler/WorkerFarm.js index ac2a1c3a0d..b13615feda 100644 --- a/packages/metro/src/DeltaBundler/WorkerFarm.js +++ b/packages/metro/src/DeltaBundler/WorkerFarm.js @@ -39,10 +39,11 @@ class WorkerFarm { constructor(config: ConfigT, transformerConfig: TransformerConfig) { this._config = config; this._transformerConfig = transformerConfig; + const absoluteWorkerPath = require.resolve(config.transformer.workerPath); if (this._config.maxWorkers > 1) { const worker = this._makeFarm( - this._config.transformer.workerPath, + absoluteWorkerPath, ['transform'], this._config.maxWorkers, ); @@ -107,7 +108,7 @@ class WorkerFarm { } _makeFarm( - workerPath: string, + absoluteWorkerPath: string, exposedMethods: $ReadOnlyArray, numWorkers: number, ): any { @@ -117,7 +118,7 @@ class WorkerFarm { FORCE_COLOR: 1, }; - return new JestWorker(workerPath, { + return new JestWorker(absoluteWorkerPath, { computeWorkerKey: this._config.stickyWorkers ? // $FlowFixMe[method-unbinding] added when improving typing for this parameters // $FlowFixMe[incompatible-call]