From 08e7f76572487dca10c61d339c9faf9e799cc516 Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 3 Jun 2025 09:53:06 +0200 Subject: [PATCH 1/7] Avoid a second graph build when getting assets --- packages/metro/src/Server.js | 21 ++++++++++++++------- packages/metro/src/index.flow.js | 11 +++++++---- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 0ff4591183..321bd76bd6 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -214,6 +214,7 @@ class Server { async build(options: BundleOptions): Promise<{ code: string, map: string, + graph: ReadOnlyGraph, ... }> { const { @@ -304,6 +305,7 @@ class Server { return { code: bundleCode, map: bundleMap, + graph, }; } @@ -366,16 +368,21 @@ class Server { }); } - async getAssets(options: BundleOptions): Promise<$ReadOnlyArray> { + async getAssets( + options: BundleOptions, + graph?: ReadOnlyGraph, + ): Promise<$ReadOnlyArray> { const {entryFile, onProgress, resolverOptions, transformOptions} = splitBundleOptions(options); - const dependencies = await this._bundler.getDependencies( - [entryFile], - transformOptions, - resolverOptions, - {onProgress, shallow: false, lazy: false}, - ); + const dependencies = + graph?.dependencies ?? + (await this._bundler.getDependencies( + [entryFile], + transformOptions, + resolverOptions, + {onProgress, shallow: false, lazy: false}, + )); return await getAssets(dependencies, { processModuleFilter: this._config.serializer.processModuleFilter, diff --git a/packages/metro/src/index.flow.js b/packages/metro/src/index.flow.js index 25735387d8..fde4fe9edb 100644 --- a/packages/metro/src/index.flow.js +++ b/packages/metro/src/index.flow.js @@ -432,10 +432,13 @@ exports.runBuild = async ( const result: RunBuildResult = {...metroBundle}; if (assets) { - result.assets = await metroServer.getAssets({ - ...MetroServer.DEFAULT_BUNDLE_OPTIONS, - ...requestOptions, - }); + result.assets = await metroServer.getAssets( + { + ...MetroServer.DEFAULT_BUNDLE_OPTIONS, + ...requestOptions, + }, + metroBundle.graph, + ); } if (onComplete) { From 59b441e98a832fc4415861ad67808d65ff2744d2 Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:23:33 +0200 Subject: [PATCH 2/7] fix types --- packages/metro/src/Server.js | 4 ++-- packages/metro/src/index.flow.js | 1 + packages/metro/src/shared/output/bundle.flow.js | 2 ++ packages/metro/types/shared/output/bundle.d.ts | 2 ++ 4 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 321bd76bd6..72eae1b360 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -214,7 +214,7 @@ class Server { async build(options: BundleOptions): Promise<{ code: string, map: string, - graph: ReadOnlyGraph, + graph?: ReadOnlyGraph<>, ... }> { const { @@ -370,7 +370,7 @@ class Server { async getAssets( options: BundleOptions, - graph?: ReadOnlyGraph, + graph?: ReadOnlyGraph<>, ): Promise<$ReadOnlyArray> { const {entryFile, onProgress, resolverOptions, transformOptions} = splitBundleOptions(options); diff --git a/packages/metro/src/index.flow.js b/packages/metro/src/index.flow.js index fde4fe9edb..0a651fef3b 100644 --- a/packages/metro/src/index.flow.js +++ b/packages/metro/src/index.flow.js @@ -111,6 +111,7 @@ export type RunBuildOptions = { ) => Promise<{ code: string, map: string, + graph?: ReadOnlyGraph<>, ... }>, save: ( diff --git a/packages/metro/src/shared/output/bundle.flow.js b/packages/metro/src/shared/output/bundle.flow.js index 241a707c37..38007d4242 100644 --- a/packages/metro/src/shared/output/bundle.flow.js +++ b/packages/metro/src/shared/output/bundle.flow.js @@ -11,6 +11,7 @@ 'use strict'; +import type {ReadOnlyGraph} from '../../DeltaBundler/types.flow'; import type {OutputOptions, RequestOptions} from '../types.flow'; import type {MixedSourceMap} from 'metro-source-map'; @@ -24,6 +25,7 @@ function buildBundle( ): Promise<{ code: string, map: string, + graph?: ReadOnlyGraph<>, ... }> { return packagerClient.build({ diff --git a/packages/metro/types/shared/output/bundle.d.ts b/packages/metro/types/shared/output/bundle.d.ts index 6ccca99d19..2b9a87e271 100644 --- a/packages/metro/types/shared/output/bundle.d.ts +++ b/packages/metro/types/shared/output/bundle.d.ts @@ -8,6 +8,7 @@ * @oncall react_native */ +import {ReadOnlyGraph} from '../../DeltaBundler/types.flow'; import Server from '../../Server'; import {OutputOptions, RequestOptions} from '../../shared/types'; @@ -17,6 +18,7 @@ export function build( ): Promise<{ code: string; map: string; + graph?: ReadOnlyGraph; }>; export function save( From 53a2d8f0049cfa40905834e233071d54fb1b288c Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:26:10 +0200 Subject: [PATCH 3/7] update test --- packages/metro/src/integration_tests/__tests__/build-test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/metro/src/integration_tests/__tests__/build-test.js b/packages/metro/src/integration_tests/__tests__/build-test.js index 3eb8344bcc..cabc831087 100644 --- a/packages/metro/src/integration_tests/__tests__/build-test.js +++ b/packages/metro/src/integration_tests/__tests__/build-test.js @@ -111,6 +111,7 @@ test('allows specifying paths to save bundle and maps', async () => { { code: expect.any(String), map: expect.any(String), + graph: expect.any(Object), }, expect.objectContaining({ bundleOutput: 'TestBundle.jsbundle', From 1bd156657f40df194f358fed41a00c44814df804 Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Tue, 3 Jun 2025 10:28:49 +0200 Subject: [PATCH 4/7] fix `.d.ts` --- packages/metro/types/shared/output/bundle.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/metro/types/shared/output/bundle.d.ts b/packages/metro/types/shared/output/bundle.d.ts index 2b9a87e271..a4a5396b7f 100644 --- a/packages/metro/types/shared/output/bundle.d.ts +++ b/packages/metro/types/shared/output/bundle.d.ts @@ -8,7 +8,7 @@ * @oncall react_native */ -import {ReadOnlyGraph} from '../../DeltaBundler/types.flow'; +import {ReadOnlyGraph} from '../../DeltaBundler/types'; import Server from '../../Server'; import {OutputOptions, RequestOptions} from '../../shared/types'; From 1c6ec97f27c470000945eeae371e128f7516078d Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Tue, 10 Jun 2025 16:02:54 +0100 Subject: [PATCH 5/7] rob: Refactor to pass assets back from build --- packages/metro/src/Server.js | 110 ++++++++++++------ packages/metro/src/index.flow.js | 16 ++- .../integration_tests/__tests__/build-test.js | 1 - packages/metro/src/lib/splitBundleOptions.js | 1 + .../metro/src/shared/output/bundle.flow.js | 4 +- packages/metro/src/shared/types.flow.js | 19 +-- packages/metro/types/Server.d.ts | 2 + packages/metro/types/index.d.ts | 2 + .../metro/types/shared/output/bundle.d.ts | 4 +- packages/metro/types/shared/types.d.ts | 2 + 10 files changed, 105 insertions(+), 56 deletions(-) diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 72eae1b360..148effabdb 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -17,6 +17,7 @@ import type {RamBundleInfo} from './DeltaBundler/Serializers/getRamBundleInfo'; import type { MixedOutput, Module, + ReadOnlyDependencies, ReadOnlyGraph, TransformInputOptions, TransformResult, @@ -211,31 +212,22 @@ class Server { return this._createModuleId; } - async build(options: BundleOptions): Promise<{ - code: string, - map: string, - graph?: ReadOnlyGraph<>, - ... - }> { + async _serializeGraph({ + splitOptions, + prepend, + graph, + }: $ReadOnly<{ + splitOptions: SplitBundleOptions, + prepend: $ReadOnlyArray>, + graph: ReadOnlyGraph<>, + }>): Promise<{code: string, map: string}> { const { entryFile, graphOptions, - onProgress, resolverOptions, serializerOptions, transformOptions, - } = splitBundleOptions(options); - - const {prepend, graph} = await this._bundler.buildGraph( - entryFile, - transformOptions, - resolverOptions, - { - onProgress, - shallow: graphOptions.shallow, - lazy: graphOptions.lazy, - }, - ); + } = splitOptions; const entryPoint = this._getEntryPointAbsolutePath(entryFile); @@ -305,7 +297,53 @@ class Server { return { code: bundleCode, map: bundleMap, - graph, + }; + } + + async build(options: BundleOptions): Promise<{ + code: string, + map: string, + assets?: $ReadOnlyArray, + ... + }> { + const splitOptions = splitBundleOptions(options); + const { + entryFile, + graphOptions, + onProgress, + resolverOptions, + transformOptions, + withAssets, + } = splitOptions; + + const {prepend, graph} = await this._bundler.buildGraph( + entryFile, + transformOptions, + resolverOptions, + { + onProgress, + shallow: graphOptions.shallow, + lazy: graphOptions.lazy, + }, + ); + + const [{code, map}, assets] = await Promise.all([ + this._serializeGraph({ + splitOptions, + prepend, + graph, + }), + withAssets + ? this._getAssetsFromDependencies(graph.dependencies, { + platform: options.platform, + }) + : null, + ]); + + return { + code, + map, + ...(withAssets ? {assets: nullthrows(assets)} : null), }; } @@ -368,26 +406,28 @@ class Server { }); } - async getAssets( - options: BundleOptions, - graph?: ReadOnlyGraph<>, - ): Promise<$ReadOnlyArray> { - const {entryFile, onProgress, resolverOptions, transformOptions} = + async getAssets(options: BundleOptions): Promise<$ReadOnlyArray> { + const {entryFile, onProgress, resolverOptions, transformOptions, platform} = splitBundleOptions(options); - const dependencies = - graph?.dependencies ?? - (await this._bundler.getDependencies( - [entryFile], - transformOptions, - resolverOptions, - {onProgress, shallow: false, lazy: false}, - )); + const dependencies = await this._bundler.getDependencies( + [entryFile], + transformOptions, + resolverOptions, + {onProgress, shallow: false, lazy: false}, + ); + + return this._getAssetsFromDependencies(dependencies, {platform}); + } + async _getAssetsFromDependencies( + dependencies: ReadOnlyDependencies<>, + {platform}: $ReadOnly<{platform: ?string}>, + ): Promise<$ReadOnlyArray> { return await getAssets(dependencies, { processModuleFilter: this._config.serializer.processModuleFilter, assetPlugins: this._config.transformer.assetPlugins, - platform: transformOptions.platform, + platform, projectRoot: this._getServerRootDir(), publicPath: this._config.transformer.publicPath, }); @@ -1497,6 +1537,7 @@ class Server { sourceMapUrl: null, sourceUrl: null, sourcePaths: SourcePathsMode, + withAssets: false, } = { ...Server.DEFAULT_GRAPH_OPTIONS, excludeSource: false, @@ -1509,6 +1550,7 @@ class Server { sourceMapUrl: null, sourceUrl: null, sourcePaths: SourcePathsMode.Absolute, + withAssets: false, }; _getServerRootDir(): string { diff --git a/packages/metro/src/index.flow.js b/packages/metro/src/index.flow.js index 0a651fef3b..db2c691247 100644 --- a/packages/metro/src/index.flow.js +++ b/packages/metro/src/index.flow.js @@ -111,7 +111,7 @@ export type RunBuildOptions = { ) => Promise<{ code: string, map: string, - graph?: ReadOnlyGraph<>, + assets?: ?$ReadOnlyArray, ... }>, save: ( @@ -422,6 +422,7 @@ exports.runBuild = async ( onProgress, customResolverOptions, customTransformOptions, + withAssets: assets, unstable_transformProfile, }; @@ -432,14 +433,11 @@ exports.runBuild = async ( const metroBundle = await output.build(metroServer, requestOptions); const result: RunBuildResult = {...metroBundle}; - if (assets) { - result.assets = await metroServer.getAssets( - { - ...MetroServer.DEFAULT_BUNDLE_OPTIONS, - ...requestOptions, - }, - metroBundle.graph, - ); + if (assets && result.assets == null) { + result.assets = await metroServer.getAssets({ + ...MetroServer.DEFAULT_BUNDLE_OPTIONS, + ...requestOptions, + }); } if (onComplete) { diff --git a/packages/metro/src/integration_tests/__tests__/build-test.js b/packages/metro/src/integration_tests/__tests__/build-test.js index cabc831087..3eb8344bcc 100644 --- a/packages/metro/src/integration_tests/__tests__/build-test.js +++ b/packages/metro/src/integration_tests/__tests__/build-test.js @@ -111,7 +111,6 @@ test('allows specifying paths to save bundle and maps', async () => { { code: expect.any(String), map: expect.any(String), - graph: expect.any(Object), }, expect.objectContaining({ bundleOutput: 'TestBundle.jsbundle', diff --git a/packages/metro/src/lib/splitBundleOptions.js b/packages/metro/src/lib/splitBundleOptions.js index cd8ab2a6dc..f4fe205902 100644 --- a/packages/metro/src/lib/splitBundleOptions.js +++ b/packages/metro/src/lib/splitBundleOptions.js @@ -46,6 +46,7 @@ function splitBundleOptions(options: BundleOptions): SplitBundleOptions { lazy: options.lazy, }, onProgress: options.onProgress, + withAssets: options.withAssets, }; } diff --git a/packages/metro/src/shared/output/bundle.flow.js b/packages/metro/src/shared/output/bundle.flow.js index 38007d4242..817dd4b34a 100644 --- a/packages/metro/src/shared/output/bundle.flow.js +++ b/packages/metro/src/shared/output/bundle.flow.js @@ -11,7 +11,7 @@ 'use strict'; -import type {ReadOnlyGraph} from '../../DeltaBundler/types.flow'; +import type {AssetData} from '../../Assets'; import type {OutputOptions, RequestOptions} from '../types.flow'; import type {MixedSourceMap} from 'metro-source-map'; @@ -25,7 +25,7 @@ function buildBundle( ): Promise<{ code: string, map: string, - graph?: ReadOnlyGraph<>, + assets?: $ReadOnlyArray, ... }> { return packagerClient.build({ diff --git a/packages/metro/src/shared/types.flow.js b/packages/metro/src/shared/types.flow.js index 95355c0f0f..1c81a2ce93 100644 --- a/packages/metro/src/shared/types.flow.js +++ b/packages/metro/src/shared/types.flow.js @@ -57,6 +57,7 @@ export type BundleOptions = { createModuleIdFactory?: () => (path: string) => number, +unstable_transformProfile: TransformProfile, +sourcePaths: SourcePathsMode, + withAssets: boolean, }; export type ResolverInputOptions = $ReadOnly<{ @@ -80,14 +81,15 @@ export type GraphOptions = { }; // Stricter representation of BundleOptions. -export type SplitBundleOptions = { - +entryFile: string, - +resolverOptions: ResolverInputOptions, - +transformOptions: TransformInputOptions, - +serializerOptions: SerializerOptions, - +graphOptions: GraphOptions, - +onProgress: DeltaBundlerOptions<>['onProgress'], -}; +export type SplitBundleOptions = $ReadOnly<{ + entryFile: string, + resolverOptions: ResolverInputOptions, + transformOptions: TransformInputOptions, + serializerOptions: SerializerOptions, + graphOptions: GraphOptions, + onProgress: DeltaBundlerOptions<>['onProgress'], + withAssets: boolean, +}>; export type ModuleGroups = { groups: Map>, @@ -140,6 +142,7 @@ export type RequestOptions = { +customResolverOptions?: CustomResolverOptions, +customTransformOptions?: CustomTransformOptions, +unstable_transformProfile?: TransformProfile, + +withAssets?: boolean, }; export type {MinifierOptions}; diff --git a/packages/metro/types/Server.d.ts b/packages/metro/types/Server.d.ts index d7be6f45d9..b8e4bd9d6a 100644 --- a/packages/metro/types/Server.d.ts +++ b/packages/metro/types/Server.d.ts @@ -85,6 +85,7 @@ export interface DefaultBundleOptions extends DefaultGraphOptions { shallow: false; sourceMapUrl: null; sourceUrl: null; + withAssets: false, } export default class Server { @@ -97,6 +98,7 @@ export default class Server { build(options: BundleOptions): Promise<{ code: string; map: string; + asset?: ReadonlyArray; }>; getRamBundleInfo(options: BundleOptions): Promise; getAssets(options: BundleOptions): Promise>; diff --git a/packages/metro/types/index.d.ts b/packages/metro/types/index.d.ts index 135544aef7..cd321031cb 100644 --- a/packages/metro/types/index.d.ts +++ b/packages/metro/types/index.d.ts @@ -14,6 +14,7 @@ export * from './ModuleGraph/worker/collectDependencies'; export * from './Server'; export * from './lib/reporting'; +import type {AssetData} from './Asset'; import type {ReadOnlyGraph} from './DeltaBundler/types'; import type {ServerOptions, default as MetroServer} from './Server'; import type {OutputOptions, RequestOptions} from './shared/types'; @@ -97,6 +98,7 @@ export interface RunBuildOptions { ) => Promise<{ code: string; map: string; + assets?: ReadonlyArray; }>; save: ( entry: { diff --git a/packages/metro/types/shared/output/bundle.d.ts b/packages/metro/types/shared/output/bundle.d.ts index a4a5396b7f..17b6c0a1b2 100644 --- a/packages/metro/types/shared/output/bundle.d.ts +++ b/packages/metro/types/shared/output/bundle.d.ts @@ -8,7 +8,7 @@ * @oncall react_native */ -import {ReadOnlyGraph} from '../../DeltaBundler/types'; +import type {AssetData} from '../../Assets'; import Server from '../../Server'; import {OutputOptions, RequestOptions} from '../../shared/types'; @@ -18,7 +18,7 @@ export function build( ): Promise<{ code: string; map: string; - graph?: ReadOnlyGraph; + assets?: ReadonlyArray; }>; export function save( diff --git a/packages/metro/types/shared/types.d.ts b/packages/metro/types/shared/types.d.ts index edc8798067..813e951594 100644 --- a/packages/metro/types/shared/types.d.ts +++ b/packages/metro/types/shared/types.d.ts @@ -44,6 +44,7 @@ export interface BundleOptions { sourceMapUrl?: string; sourceUrl?: string; createModuleIdFactory?: () => (path: string) => number; + readonly withAssets: boolean; readonly unstable_transformProfile: TransformProfile; } @@ -122,6 +123,7 @@ export interface RequestOptions { platform: string; createModuleIdFactory?: () => (path: string) => number; onProgress?: (transformedFileCount: number, totalFileCount: number) => void; + withAssets?: boolean; } export type {MinifierOptions}; From bf3b5cc5e01ce180b0d71ff8e11290bb44f42399 Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:26:15 +0100 Subject: [PATCH 6/7] Introduce BuildOptions rather than adding withAssets to BundleOptions --- packages/metro/src/Server.js | 20 +++++++++++-------- packages/metro/src/index.flow.js | 9 ++++++--- packages/metro/src/lib/splitBundleOptions.js | 1 - .../metro/src/shared/output/bundle.flow.js | 14 ++++++++----- packages/metro/src/shared/types.flow.js | 7 ++++--- packages/metro/types/Server.d.ts | 9 ++++++--- packages/metro/types/index.d.ts | 5 +++-- .../metro/types/shared/output/bundle.d.ts | 6 ++++-- packages/metro/types/shared/types.d.ts | 6 ++++-- 9 files changed, 48 insertions(+), 29 deletions(-) diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 148effabdb..3e93c82f4a 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -27,6 +27,7 @@ import type {GraphId} from './lib/getGraphId'; import type {Reporter} from './lib/reporting'; import type {StackFrameInput, StackFrameOutput} from './Server/symbolicate'; import type { + BuildOptions, BundleOptions, GraphOptions, ResolverInputOptions, @@ -300,20 +301,22 @@ class Server { }; } - async build(options: BundleOptions): Promise<{ + async build( + bundleOptions: BundleOptions, + {withAssets}: BuildOptions = {}, + ): Promise<{ code: string, map: string, assets?: $ReadOnlyArray, ... }> { - const splitOptions = splitBundleOptions(options); + const splitOptions = splitBundleOptions(bundleOptions); const { entryFile, graphOptions, onProgress, resolverOptions, transformOptions, - withAssets, } = splitOptions; const {prepend, graph} = await this._bundler.buildGraph( @@ -335,7 +338,7 @@ class Server { }), withAssets ? this._getAssetsFromDependencies(graph.dependencies, { - platform: options.platform, + platform: bundleOptions.platform, }) : null, ]); @@ -407,7 +410,7 @@ class Server { } async getAssets(options: BundleOptions): Promise<$ReadOnlyArray> { - const {entryFile, onProgress, resolverOptions, transformOptions, platform} = + const {entryFile, onProgress, resolverOptions, transformOptions} = splitBundleOptions(options); const dependencies = await this._bundler.getDependencies( @@ -417,11 +420,14 @@ class Server { {onProgress, shallow: false, lazy: false}, ); - return this._getAssetsFromDependencies(dependencies, {platform}); + return this._getAssetsFromDependencies(dependencies, { + platform: transformOptions.platform, + }); } async _getAssetsFromDependencies( dependencies: ReadOnlyDependencies<>, + {platform}: $ReadOnly<{platform: ?string}>, ): Promise<$ReadOnlyArray> { return await getAssets(dependencies, { @@ -1537,7 +1543,6 @@ class Server { sourceMapUrl: null, sourceUrl: null, sourcePaths: SourcePathsMode, - withAssets: false, } = { ...Server.DEFAULT_GRAPH_OPTIONS, excludeSource: false, @@ -1550,7 +1555,6 @@ class Server { sourceMapUrl: null, sourceUrl: null, sourcePaths: SourcePathsMode.Absolute, - withAssets: false, }; _getServerRootDir(): string { diff --git a/packages/metro/src/index.flow.js b/packages/metro/src/index.flow.js index db2c691247..eed42be8eb 100644 --- a/packages/metro/src/index.flow.js +++ b/packages/metro/src/index.flow.js @@ -14,6 +14,7 @@ import type {AssetData} from './Assets'; import type {ReadOnlyGraph} from './DeltaBundler'; import type {ServerOptions} from './Server'; +import type {BuildOptions} from './shared/types.flow'; import type {OutputOptions, RequestOptions} from './shared/types.flow.js'; import type {HandleFunction} from 'connect'; import type {Server as HttpServer} from 'http'; @@ -108,10 +109,11 @@ export type RunBuildOptions = { build: ( MetroServer, RequestOptions, + void | BuildOptions, ) => Promise<{ code: string, map: string, - assets?: ?$ReadOnlyArray, + assets?: $ReadOnlyArray, ... }>, save: ( @@ -422,7 +424,6 @@ exports.runBuild = async ( onProgress, customResolverOptions, customTransformOptions, - withAssets: assets, unstable_transformProfile, }; @@ -430,7 +431,9 @@ exports.runBuild = async ( onBegin(); } - const metroBundle = await output.build(metroServer, requestOptions); + const metroBundle = await output.build(metroServer, requestOptions, { + withAssets: assets, + }); const result: RunBuildResult = {...metroBundle}; if (assets && result.assets == null) { diff --git a/packages/metro/src/lib/splitBundleOptions.js b/packages/metro/src/lib/splitBundleOptions.js index f4fe205902..cd8ab2a6dc 100644 --- a/packages/metro/src/lib/splitBundleOptions.js +++ b/packages/metro/src/lib/splitBundleOptions.js @@ -46,7 +46,6 @@ function splitBundleOptions(options: BundleOptions): SplitBundleOptions { lazy: options.lazy, }, onProgress: options.onProgress, - withAssets: options.withAssets, }; } diff --git a/packages/metro/src/shared/output/bundle.flow.js b/packages/metro/src/shared/output/bundle.flow.js index 817dd4b34a..e13b635fc0 100644 --- a/packages/metro/src/shared/output/bundle.flow.js +++ b/packages/metro/src/shared/output/bundle.flow.js @@ -12,7 +12,7 @@ 'use strict'; import type {AssetData} from '../../Assets'; -import type {OutputOptions, RequestOptions} from '../types.flow'; +import type {BuildOptions, OutputOptions, RequestOptions} from '../types.flow'; import type {MixedSourceMap} from 'metro-source-map'; const relativizeSourceMapInline = require('../../lib/relativizeSourceMap'); @@ -22,16 +22,20 @@ const writeFile = require('./writeFile'); function buildBundle( packagerClient: Server, requestOptions: RequestOptions, + buildOptions?: BuildOptions = {}, ): Promise<{ code: string, map: string, assets?: $ReadOnlyArray, ... }> { - return packagerClient.build({ - ...Server.DEFAULT_BUNDLE_OPTIONS, - ...requestOptions, - }); + return packagerClient.build( + { + ...Server.DEFAULT_BUNDLE_OPTIONS, + ...requestOptions, + }, + buildOptions, + ); } function relativateSerializedMap( diff --git a/packages/metro/src/shared/types.flow.js b/packages/metro/src/shared/types.flow.js index 1c81a2ce93..80f100592c 100644 --- a/packages/metro/src/shared/types.flow.js +++ b/packages/metro/src/shared/types.flow.js @@ -57,9 +57,12 @@ export type BundleOptions = { createModuleIdFactory?: () => (path: string) => number, +unstable_transformProfile: TransformProfile, +sourcePaths: SourcePathsMode, - withAssets: boolean, }; +export type BuildOptions = $ReadOnly<{ + withAssets?: boolean, +}>; + export type ResolverInputOptions = $ReadOnly<{ customResolverOptions?: CustomResolverOptions, dev: boolean, @@ -88,7 +91,6 @@ export type SplitBundleOptions = $ReadOnly<{ serializerOptions: SerializerOptions, graphOptions: GraphOptions, onProgress: DeltaBundlerOptions<>['onProgress'], - withAssets: boolean, }>; export type ModuleGroups = { @@ -142,7 +144,6 @@ export type RequestOptions = { +customResolverOptions?: CustomResolverOptions, +customTransformOptions?: CustomTransformOptions, +unstable_transformProfile?: TransformProfile, - +withAssets?: boolean, }; export type {MinifierOptions}; diff --git a/packages/metro/types/Server.d.ts b/packages/metro/types/Server.d.ts index b8e4bd9d6a..c442f7abb1 100644 --- a/packages/metro/types/Server.d.ts +++ b/packages/metro/types/Server.d.ts @@ -13,6 +13,7 @@ import type {RamBundleInfo} from './DeltaBundler/Serializers/getRamBundleInfo'; import type {GraphId} from './lib/getGraphId'; import type MultipartResponse from './Server/MultipartResponse'; import type { + BuildOptions, BundleOptions, GraphOptions, SplitBundleOptions, @@ -85,7 +86,6 @@ export interface DefaultBundleOptions extends DefaultGraphOptions { shallow: false; sourceMapUrl: null; sourceUrl: null; - withAssets: false, } export default class Server { @@ -95,10 +95,13 @@ export default class Server { end(): void; getBundler(): IncrementalBundler; getCreateModuleId(): (path: string) => number; - build(options: BundleOptions): Promise<{ + build( + bundleOptions: BundleOptions, + buildOptions?: BuildOptions, + ): Promise<{ code: string; map: string; - asset?: ReadonlyArray; + assets?: ReadonlyArray; }>; getRamBundleInfo(options: BundleOptions): Promise; getAssets(options: BundleOptions): Promise>; diff --git a/packages/metro/types/index.d.ts b/packages/metro/types/index.d.ts index cd321031cb..7446d355fb 100644 --- a/packages/metro/types/index.d.ts +++ b/packages/metro/types/index.d.ts @@ -17,7 +17,7 @@ export * from './lib/reporting'; import type {AssetData} from './Asset'; import type {ReadOnlyGraph} from './DeltaBundler/types'; import type {ServerOptions, default as MetroServer} from './Server'; -import type {OutputOptions, RequestOptions} from './shared/types'; +import type {BuildOptions, OutputOptions, RequestOptions} from './shared/types'; import type {HandleFunction} from 'connect'; import type {EventEmitter} from 'events'; import type {IncomingMessage, Server as HttpServer} from 'http'; @@ -94,7 +94,8 @@ export interface RunBuildOptions { output?: { build: ( server: MetroServer, - options: RequestOptions, + requestOptions: RequestOptions, + buildOptions?: BuildOptions, ) => Promise<{ code: string; map: string; diff --git a/packages/metro/types/shared/output/bundle.d.ts b/packages/metro/types/shared/output/bundle.d.ts index 17b6c0a1b2..06c5fe6945 100644 --- a/packages/metro/types/shared/output/bundle.d.ts +++ b/packages/metro/types/shared/output/bundle.d.ts @@ -8,13 +8,15 @@ * @oncall react_native */ -import type {AssetData} from '../../Assets'; +import type {AssetData} from '../../Asset'; + import Server from '../../Server'; -import {OutputOptions, RequestOptions} from '../../shared/types'; +import {BuildOptions, OutputOptions, RequestOptions} from '../../shared/types'; export function build( packagerClient: Server, requestOptions: RequestOptions, + buildOptions?: BuildOptions, ): Promise<{ code: string; map: string; diff --git a/packages/metro/types/shared/types.d.ts b/packages/metro/types/shared/types.d.ts index 813e951594..bd6bd81d97 100644 --- a/packages/metro/types/shared/types.d.ts +++ b/packages/metro/types/shared/types.d.ts @@ -44,10 +44,13 @@ export interface BundleOptions { sourceMapUrl?: string; sourceUrl?: string; createModuleIdFactory?: () => (path: string) => number; - readonly withAssets: boolean; readonly unstable_transformProfile: TransformProfile; } +export interface BuildOptions { + readonly withAssets?: boolean; +} + export interface ResolverInputOptions { readonly customResolverOptions?: CustomResolverOptions; } @@ -123,7 +126,6 @@ export interface RequestOptions { platform: string; createModuleIdFactory?: () => (path: string) => number; onProgress?: (transformedFileCount: number, totalFileCount: number) => void; - withAssets?: boolean; } export type {MinifierOptions}; From a9ad6f0d52515e88a422e5fea49b61172c2900d3 Mon Sep 17 00:00:00 2001 From: Rob Hogan <2590098+robhogan@users.noreply.github.com> Date: Wed, 11 Jun 2025 11:35:56 +0100 Subject: [PATCH 7/7] Update Server.js --- packages/metro/src/Server.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/metro/src/Server.js b/packages/metro/src/Server.js index 3e93c82f4a..b29e304a0d 100644 --- a/packages/metro/src/Server.js +++ b/packages/metro/src/Server.js @@ -337,9 +337,10 @@ class Server { graph, }), withAssets - ? this._getAssetsFromDependencies(graph.dependencies, { - platform: bundleOptions.platform, - }) + ? this._getAssetsFromDependencies( + graph.dependencies, + bundleOptions.platform, + ) : null, ]); @@ -420,15 +421,15 @@ class Server { {onProgress, shallow: false, lazy: false}, ); - return this._getAssetsFromDependencies(dependencies, { - platform: transformOptions.platform, - }); + return this._getAssetsFromDependencies( + dependencies, + transformOptions.platform, + ); } async _getAssetsFromDependencies( dependencies: ReadOnlyDependencies<>, - - {platform}: $ReadOnly<{platform: ?string}>, + platform: ?string, ): Promise<$ReadOnlyArray> { return await getAssets(dependencies, { processModuleFilter: this._config.serializer.processModuleFilter,