Skip to content

Commit

Permalink
lazily import metro-hermes-compiler (#856)
Browse files Browse the repository at this point in the history
Summary:
- There are [general performance improvements](#855) from conditionally importing Hermes.
- `metro-hermes-compiler` is doing some gnarly error handling that makes debugging Metro quite painful.

If you get an error in Metro after `metro-hermes-compiler` has been loaded, it will look something like:

<img width="1900" alt="Screen Shot 2022-08-23 at 1 28 43 PM" src="https://user-images.githubusercontent.com/9664363/186146899-57817ce9-9cef-439b-a421-98b9aec216fb.png">

This PR doesn't fix the core issue but it does alleviate Metro web and JSC development where Hermes is not used:

```
TypeError [ERR_INVALID_ARG_TYPE]: The "to" argument must be of type string. Received undefined
    at new NodeError (node:internal/errors:371:5)
    at validateString (node:internal/validators:119:11)
    at Object.relative (node:path:1192:5)
    at MetroTerminalReporter._getBundleStatusMessage (/Users/evanbacon/Documents/GitHub/expo/packages/expo/cli/build/src/start/server/metro/MetroTerminalReporter.js:44:41)
    at /Users/evanbacon/Documents/GitHub/expo/node_modules/metro/src/lib/TerminalReporter.js:393:14
    at Array.map (<anonymous>)
    at MetroTerminalReporter._getStatusMessage (/Users/evanbacon/Documents/GitHub/expo/node_modules/metro/src/lib/TerminalReporter.js:392:8)
    at MetroTerminalReporter.update (/Users/evanbacon/Documents/GitHub/expo/node_modules/metro/src/lib/TerminalReporter.js:423:31)
    at Object.update (/Users/evanbacon/Documents/GitHub/expo/packages/expo/cli/build/src/start/server/metro/instantiateMetro.js:21:30)
    at Server.requestProcessor [as _processBundleRequest] (/Users/evanbacon/Documents/GitHub/metro/packages/metro/src/Server.js:653:22)
    at async Server._processRequest (/Users/evanbacon/Documents/GitHub/metro/packages/metro/src/Server.js:504:9)
```

Pull Request resolved: #856

Test Plan: Throw an error somewhere in the resolver, Metro will throw a reasonable Node error instead of the Hermes error.

Reviewed By: motiz88

Differential Revision: D38940701

Pulled By: cipolleschi

fbshipit-source-id: 472fa775c5ae6a39acb6d0195f926a1013a4b425
  • Loading branch information
EvanBacon authored and facebook-github-bot committed Aug 25, 2022
1 parent a028507 commit 71846a4
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/metro-transform-worker/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ const babylon = require('@babel/parser');
const types = require('@babel/types');
const {stableHash} = require('metro-cache');
const getCacheKey = require('metro-cache-key');
const HermesCompiler = require('metro-hermes-compiler');
const {
fromRawMappings,
toBabelSegments,
Expand Down Expand Up @@ -260,6 +259,7 @@ const compileToBytecode = (
',$$METRO_D[0],$$METRO_D[1],$$METRO_D[2]' +
code.slice(index);
}
const HermesCompiler = require('metro-hermes-compiler');
return HermesCompiler.compile(code, options);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import type {BytecodeBundle} from 'metro-runtime/src/modules/types.flow';
const getAppendScripts = require('../../lib/getAppendScripts');
const {getJsOutput} = require('./helpers/js');
const processBytecodeModules = require('./helpers/processBytecodeModules');
const {compile} = require('metro-hermes-compiler');

function baseBytecodeBundle(
entryPoint: string,
Expand Down Expand Up @@ -50,6 +49,8 @@ function baseBytecodeBundle(
options.createModuleId(a.path) - options.createModuleId(b.path),
);

const {compile} = require('metro-hermes-compiler');

const post = processBytecodeModules(
getAppendScripts(
entryPoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import type {Module} from '../../types.flow';
import type {BytecodeOutput} from 'metro-transform-worker';

const invariant = require('invariant');
const {compile} = require('metro-hermes-compiler');
const path = require('path');

export type Options = {
Expand Down Expand Up @@ -48,6 +47,8 @@ function wrapModule(module: Module<>, options: Options): Array<Buffer> {
);
}

const {compile} = require('metro-hermes-compiler');

const headerCode = `globalThis.$$METRO_D=[${params.join(',')}];`;
return [
compile(headerCode, {
Expand Down
7 changes: 5 additions & 2 deletions packages/metro/src/HmrServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const transformHelpers = require('./lib/transformHelpers');
const {
Logger: {createActionStartEntry, createActionEndEntry, log},
} = require('metro-core');
const {VERSION: BYTECODE_VERSION} = require('metro-hermes-compiler');
const nullthrows = require('nullthrows');
const url = require('url');

Expand All @@ -51,6 +50,10 @@ type ClientGroup = {
+unlisten: () => void,
};

function getBytecodeVersion() {
return require('metro-hermes-compiler').VERSION;
}

function send(sendFns: Array<(string) => void>, message: HmrMessage): void {
const strMessage = JSON.stringify(message);
sendFns.forEach((sendFn: string => void) => sendFn(strMessage));
Expand Down Expand Up @@ -103,7 +106,7 @@ class HmrServer<TClient: Client> {
const options = parseOptionsFromUrl(
requestUrl,
new Set(this._config.resolver.platforms),
BYTECODE_VERSION,
getBytecodeVersion(),
);
const {entryFile, resolverOptions, transformOptions, graphOptions} =
splitBundleOptions(options);
Expand Down
10 changes: 7 additions & 3 deletions packages/metro/src/Server.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const {
Logger,
Logger: {createActionStartEntry, createActionEndEntry, log},
} = require('metro-core');
const {VERSION: BYTECODE_VERSION} = require('metro-hermes-compiler');

const mime = require('mime-types');
const nullthrows = require('nullthrows');
const path = require('path');
Expand Down Expand Up @@ -118,6 +118,10 @@ export type ServerOptions = $ReadOnly<{
const DELTA_ID_HEADER = 'X-Metro-Delta-ID';
const FILES_CHANGED_COUNT_HEADER = 'X-Metro-Files-Changed-Count';

function getBytecodeVersion() {
return require('metro-hermes-compiler').VERSION;
}

class Server {
_bundler: IncrementalBundler;
_config: ConfigT;
Expand Down Expand Up @@ -467,7 +471,7 @@ class Server {
return parseOptionsFromUrl(
url,
new Set(this._config.resolver.platforms),
BYTECODE_VERSION,
getBytecodeVersion(),
);
}

Expand Down Expand Up @@ -1201,7 +1205,7 @@ class Server {
const options = parseOptionsFromUrl(
reqUrl,
new Set(this._config.resolver.platforms),
BYTECODE_VERSION,
getBytecodeVersion(),
);

const {
Expand Down
4 changes: 2 additions & 2 deletions packages/metro/src/lib/bundleToBytecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import type {
BytecodeBundle,
} from 'metro-runtime/src/modules/types.flow';

const {getFileLength} = require('metro-hermes-compiler');

// The magic number is used as a header for bytecode.
// It represents a Metro tunnel in binary.
//
Expand All @@ -34,6 +32,8 @@ function getFileHeader(moduleCount: number): Buffer {
}

function addModuleHeader(buffer: Buffer): [Buffer, Buffer] {
const {getFileLength} = require('metro-hermes-compiler');

const fileLength = getFileLength(buffer, 0);
const header = Buffer.alloc(4);
header.writeUInt32LE(fileLength, 0);
Expand Down
3 changes: 2 additions & 1 deletion packages/metro/src/lib/getPrependedScripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ const countLines = require('./countLines');
const getPreludeCode = require('./getPreludeCode');
const transformHelpers = require('./transformHelpers');
const defaults = require('metro-config/src/defaults/defaults');
const {compile} = require('metro-hermes-compiler');

async function getPrependedScripts(
config: ConfigT,
Expand Down Expand Up @@ -93,6 +92,8 @@ function _getPrelude({
requireCycleIgnorePatterns: $ReadOnlyArray<RegExp>,
...
}): Module<> {
const {compile} = require('metro-hermes-compiler');

const code = getPreludeCode({
isDev: dev,
globalPrefix,
Expand Down

0 comments on commit 71846a4

Please sign in to comment.