Skip to content

Commit

Permalink
Add metro app building support (#44466)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #44466

Contains a *light* wrapper to help launch Metro and build bundles or wait for localhost requests against Metro's dev-server.

Changelog: [Internal]

Reviewed By: cipolleschi

Differential Revision: D57067040

fbshipit-source-id: 8ab7ecb5d9b98d1abddd5d4f04c7eb25129cd0a1
  • Loading branch information
blakef authored and facebook-github-bot committed May 13, 2024
1 parent fd8f1f5 commit 9b0072a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/core-cli-utils/src/index.flow.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
// @babel/register doesn't like export {foo} from './bar'; statements,
// so we have to jump through hoops here.
import {tasks as _android} from './private/android.js';
import {tasks as _app} from './private/app.js';
import {tasks as _apple} from './private/apple.js';
import {tasks as _clean} from './private/clean.js';
import * as _version from './public/version.js';

export const android = _android;
export const app = _app;
export const apple = _apple;
export const clean = _clean;
export const version = _version;
Expand Down
71 changes: 71 additions & 0 deletions packages/core-cli-utils/src/private/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
* @oncall react_native
*/

import type {Task} from './types';
import type {ExecaPromise} from 'execa';

import {task} from './utils';
import execa from 'execa';
import path from 'path';

type AppOptions = {
cwd: string,
};

type BundleOptions =
| {mode: 'bundle', ...AppOptions}
| {mode: 'watch', callback?: (metro: ExecaPromise) => void, ...AppOptions};

const FIRST = 1,
SECOND = 2;

function getNodePackagePath(packageName: string): string {
// $FlowFixMe[prop-missing] type definition is incomplete
return require.resolve(packageName, {cwd: [process.cwd(), ...module.paths]});
}

function metro(...args: $ReadOnlyArray<string>): ExecaPromise {
return execa('node', [
getNodePackagePath(path.join('metro', 'src', 'cli.js')),
...args,
]);
}

const noMetro = new Error('Metro is not available');

export const tasks = {
bundle: (
options: BundleOptions,
...args: $ReadOnlyArray<string>
): {
validate: Task<void>,
run: Task<ExecaPromise>,
} => ({
/* eslint-disable sort-keys */
validate: task(FIRST, 'Check if Metro is available', () => {
try {
require('metro');
} catch {
throw noMetro;
}
}),

run:
options.mode === 'bundle'
? task(SECOND, 'Metro generating an .jsbundle', () =>
metro('bundle', ...args),
)
: task(SECOND, 'Metro watching for changes', () => {
const proc = metro('serve', ...args);
return proc;
}),
}),
};

0 comments on commit 9b0072a

Please sign in to comment.