mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
community-cli-plugin: Refactor CLI build command to use Metro.runBuild (#51124)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/51124 Metro 0.82.3's `runBuild` API now supports retrieving assets and passing through `unstable_transformProfile`, and fine control of output paths via `bundleOut`/`sourcemapOut`, so we can use it directly in the implementation of `community-cli-plugin`'s `bundle` command with no loss of function or API change. This simplifies the implementation by re-using Metro's, and removes use of Metro internal APIs. Changelog: [Internal] Reviewed By: huntie Differential Revision: D74151840
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7af8c01f46
commit
342afb9cd8
@@ -9,17 +9,15 @@
|
||||
*/
|
||||
|
||||
import type {Config} from '@react-native-community/cli-types';
|
||||
import type {RunBuildOptions} from 'metro';
|
||||
import type {ConfigT} from 'metro-config';
|
||||
import type {RequestOptions} from 'metro/src/shared/types.flow';
|
||||
|
||||
import loadMetroConfig from '../../utils/loadMetroConfig';
|
||||
import parseKeyValueParamArray from '../../utils/parseKeyValueParamArray';
|
||||
import saveAssets from './saveAssets';
|
||||
import chalk from 'chalk';
|
||||
import {promises as fs} from 'fs';
|
||||
import Server from 'metro/src/Server';
|
||||
import metroBundle from 'metro/src/shared/output/bundle';
|
||||
import metroRamBundle from 'metro/src/shared/output/RamBundle';
|
||||
import {runBuild} from 'metro';
|
||||
import path from 'path';
|
||||
|
||||
export type BundleCommandArgs = {
|
||||
@@ -40,7 +38,7 @@ export type BundleCommandArgs = {
|
||||
sourcemapSourcesRoot?: string,
|
||||
sourcemapUseAbsolutePath: boolean,
|
||||
verbose: boolean,
|
||||
unstableTransformProfile: string,
|
||||
unstableTransformProfile: 'hermes-stable' | 'hermes-canary' | 'default',
|
||||
indexedRamBundle?: boolean,
|
||||
resolverOption?: Array<string>,
|
||||
};
|
||||
@@ -49,7 +47,7 @@ async function buildBundle(
|
||||
_argv: Array<string>,
|
||||
ctx: Config,
|
||||
args: BundleCommandArgs,
|
||||
bundleImpl: typeof metroBundle | typeof metroRamBundle = metroBundle,
|
||||
bundleImpl?: RunBuildOptions['output'],
|
||||
): Promise<void> {
|
||||
const config = await loadMetroConfig(ctx, {
|
||||
maxWorkers: args.maxWorkers,
|
||||
@@ -63,7 +61,7 @@ async function buildBundle(
|
||||
async function buildBundleWithConfig(
|
||||
args: BundleCommandArgs,
|
||||
config: ConfigT,
|
||||
bundleImpl: typeof metroBundle | typeof metroRamBundle = metroBundle,
|
||||
bundleImpl?: RunBuildOptions['output'],
|
||||
): Promise<void> {
|
||||
const customResolverOptions = parseKeyValueParamArray(
|
||||
args.resolverOption ?? [],
|
||||
@@ -96,52 +94,48 @@ async function buildBundleWithConfig(
|
||||
sourceMapUrl = path.basename(sourceMapUrl);
|
||||
}
|
||||
|
||||
// $FlowIgnore[prop-missing]
|
||||
const requestOpts: RequestOptions & {...} = {
|
||||
entryFile: args.entryFile,
|
||||
sourceMapUrl,
|
||||
dev: args.dev,
|
||||
minify: args.minify !== undefined ? args.minify : !args.dev,
|
||||
platform: args.platform,
|
||||
// $FlowFixMe[incompatible-type] Remove suppression after Metro 0.82.3
|
||||
unstable_transformProfile: args.unstableTransformProfile,
|
||||
const runBuildOptions: RunBuildOptions = {
|
||||
assets: args.assetsDest != null,
|
||||
bundleOut: args.bundleOutput,
|
||||
customResolverOptions,
|
||||
dev: args.dev,
|
||||
entry: args.entryFile,
|
||||
minify: args.minify !== undefined ? args.minify : !args.dev,
|
||||
output: bundleImpl,
|
||||
platform: args.platform,
|
||||
sourceMap: args.sourcemapOutput != null,
|
||||
sourceMapOut: args.sourcemapOutput,
|
||||
sourceMapUrl,
|
||||
unstable_transformProfile: args.unstableTransformProfile,
|
||||
};
|
||||
const server = new Server(config);
|
||||
|
||||
try {
|
||||
const bundle = await bundleImpl.build(server, requestOpts);
|
||||
// Ensure destination directory exists before running the build
|
||||
await fs.mkdir(path.dirname(args.bundleOutput), {
|
||||
recursive: true,
|
||||
mode: 0o755,
|
||||
});
|
||||
|
||||
// Ensure destination directory exists before saving the bundle
|
||||
await fs.mkdir(path.dirname(args.bundleOutput), {
|
||||
recursive: true,
|
||||
mode: 0o755,
|
||||
});
|
||||
const result = await runBuild(config, runBuildOptions);
|
||||
|
||||
// $FlowIgnore[class-object-subtyping]
|
||||
// $FlowIgnore[incompatible-call]
|
||||
// $FlowIgnore[prop-missing]
|
||||
// $FlowIgnore[incompatible-exact]
|
||||
await bundleImpl.save(bundle, args, console.info);
|
||||
|
||||
// Save the assets of the bundle
|
||||
// $FlowFixMe[prop-missing] Remove suppression after Metro 0.82.3
|
||||
const outputAssets = await server.getAssets({
|
||||
...Server.DEFAULT_BUNDLE_OPTIONS,
|
||||
...requestOpts,
|
||||
bundleType: 'todo',
|
||||
});
|
||||
|
||||
// When we're done saving bundle output and the assets, we're done.
|
||||
return await saveAssets(
|
||||
outputAssets,
|
||||
args.platform,
|
||||
args.assetsDest,
|
||||
args.assetCatalogDest,
|
||||
);
|
||||
} finally {
|
||||
await server.end();
|
||||
if (args.assetsDest == null) {
|
||||
console.warn('Warning: Assets destination folder is not set, skipping...');
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the assets of the bundle
|
||||
if (result.assets == null) {
|
||||
throw new Error("Assets missing from Metro's runBuild result");
|
||||
}
|
||||
|
||||
const outputAssets = result.assets;
|
||||
|
||||
// When we're done saving bundle output and the assets, we're done.
|
||||
await saveAssets(
|
||||
outputAssets,
|
||||
args.platform,
|
||||
args.assetsDest,
|
||||
args.assetCatalogDest,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user