Skip to content

serializer.unstable_inlineDependencyMap: Add opt-in serialise-time module id inlining to the serialiser#1786

Open
robhogan wants to merge 2 commits into
mainfrom
export-D112353887
Open

serializer.unstable_inlineDependencyMap: Add opt-in serialise-time module id inlining to the serialiser#1786
robhogan wants to merge 2 commits into
mainfrom
export-D112353887

Conversation

@robhogan

Copy link
Copy Markdown
Contributor

Summary:
Wires the inlineModuleIdReferences helper (previous diff) into the OSS serialiser behind a new opt-in serializer.unstable_inlineDependencyMap, porting this Metro-Buck optimisation to core.

When serializer.unstable_inlineDependencyMap AND transformer.unstable_dependencyMapReservedName is set, each module body has its <reservedName>[i] references replaced with the resolved numeric module ID (right-padded to preserve source-map columns), and the dependency-map array argument is dropped from the __d(...) call (where it is empty AND the last argument).

For dev bundles, a null keeps that slot occupied so the verbose-name argument stays in position.

With the flag off, output is unchanged.

Threading:

  • SerializerConfigT (+ default) gains unstable_inlineDependencyMap.
  • SerializerOptions gains optional unstable_inlineDependencyMap and dependencyMapReservedName.
  • Server.js populates both at all three serialiser-options construction sites from resolved config (the reserved name is already resolved at serialise time).
  • baseJSBundle -> processModules -> wrapModule/getModuleParams thread the options.

Changelog:

 - **[Experimental]**: Add `serializer.unstable_inlineDependencyMap` for an opt-in runtime optimisation.

Differential Revision: D112353887

robhogan and others added 2 commits July 21, 2026 07:50
…k fork)

Summary:
Adds `inlineModuleIdReferences`, a pure string helper in the OSS Metro
serializer that replaces `dependencyMapReservedName[i]` references in a module
body with the resolved numeric module ID of dependency `i`. This is the generic
(mobile-agnostic) fast path that previously only existed as a fork inside the
internal metro-buck bundle worker (`src/ModuleGraph/output/util.js`
`inlineModuleIds`): it avoids a Babel parse -> transform -> generate round-trip
per module.

Each replacement is right-padded (`padEnd`) to the exact width of the reference
it replaces, so byte offsets - and therefore source-map columns - are preserved
and the source map does not need to be regenerated. An overflow guard fails the
build rather than silently emitting an incorrect source map, and a missing
reserved-name reference throws (or is ignored when opted in).

To immediately shrink the fork, the metro-buck worker's `inlineModuleIds` fast
path now delegates to this shared helper (imported via
`metro/private/DeltaBundler/Serializers/helpers/js`) and its byte-identical
regex + `escapeRegex` copy is deleted. The worker keeps its Babel slow path
(not upstreamed) and its `_$$_METRO_MODULE_ID` placeholder handling. Bundle
output is byte-for-byte unchanged, proven by the worker's e2e snapshot suites.

Note: the shared helper's "missing reserved name" error message is
path-agnostic, so it no longer prints the module file path the worker's copy
included. That is an internal error that cannot fire in production
(`unstable_dependencyMapReservedName` is always set for Metro-Buck).

The OSS serializer itself is not yet wired to use the helper; that opt-in wiring
lands in the next diff.

Differential Revision: D112353888
…dule id inlining to the serialiser

Summary:
Wires the `inlineModuleIdReferences` helper (previous diff) into the OSS serialiser behind a new opt-in `serializer.unstable_inlineDependencyMap`, porting this Metro-Buck optimisation to core.

When `serializer.unstable_inlineDependencyMap` AND `transformer.unstable_dependencyMapReservedName` is set, each module body has its `<reservedName>[i]` references replaced with the resolved numeric module ID (right-padded to preserve source-map columns), and the dependency-map array argument is dropped from the `__d(...)` call (where it is empty AND the last argument).

For dev bundles, a `null` keeps that slot occupied so the verbose-name argument stays in position.

With the flag off, output is unchanged.

Threading:
- `SerializerConfigT` (+ default) gains `unstable_inlineDependencyMap`.
- `SerializerOptions` gains optional `unstable_inlineDependencyMap` and `dependencyMapReservedName`.
- `Server.js` populates both at all three serialiser-options construction sites from resolved config (the reserved name is already resolved at serialise time).
- `baseJSBundle` -> `processModules` -> `wrapModule`/`getModuleParams` thread the options.

Changelog:
```
 - **[Experimental]**: Add `serializer.unstable_inlineDependencyMap` for an opt-in runtime optimisation.
```

Differential Revision: D112353887
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Jul 22, 2026
@meta-codesync

meta-codesync Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@robhogan has exported this pull request. If you are a Meta employee, you can view the originating Diff in D112353887.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant