Repository navigation
fix(repack): lower RN 0.81+ Flow syntax in flow-loader and keep Flow enums in Babel loaders - #1492
Conversation
…w-loader flow-remove-types only erases type annotations, so on React Native 0.81+ flow-loader (and getJsTransformRules) emitted invalid JS for `component` / `hook` declarations, Flow enums and `match` expressions. Files using them now go through the project's React Native parser (hermes-parser or flow-parser) and @babel/plugin-transform-flow-strip-types; all other files still use flow-remove-types. Enums are lowered to flow-enums-runtime, resolved from the project or from react-native so it works with isolated installs. Source maps are emitted for lowered files. Also fix flow-loader crashing under webpack: getOptions() received the loader context as a schema. Part of callstack#1422
Flow `component` declarations with a `ref` are lowered to `forwardRef` on React 18 and pass `ref` as a prop on React 19. Pick the target from the project's `react` version instead of always assuming React 19. Part of callstack#1422
@react-native/babel-preset strips Flow enum declarations before its enum plugin runs, so references such as React Native's VirtualViewMode.cast() were undefined at runtime. Parse @flow sources with the shared parseReactNativeSource helper, which lowers enums to flow-enums-runtime and picks the component lowering target from the project's React version (hermesParserOverrides still take precedence). Related to callstack#1422
- detect multi-line `match (...)` in flow-loader's prefilter and cover the routing with unit tests - strip class fields of lowered files like flow-remove-types does: allow `declare` fields and honour `ignoreUninitializedFields` - require @babel/core only when a file needs lowering - cache flow-enums-runtime and React version lookups per project root - share the preset lookup and wrap its resolution errors - pin unused import preservation in a file that is not lowered Part of callstack#1422
|
@whydidoo is attempting to deploy a commit to the Callstack Team on Vercel. A member of the Team first needs to authorize it. |
|
Addin to that @dannyhw already said here: Some notes on the enum part: The cause is in babel.transformSync('// @flow\nenum Mode { A = 0 }\nexport const x = Mode.cast(0);', {
presets: ['@react-native/babel-preset'],
});
// → var x = exports.x = Mode.cast(0); (the enum is gone)It isn't Re.Pack-specific either: a Metro bundle of the same app never defines The fix only covers files that go through the hermes-parser path. Enum lowering lives in A simpler option to consider: add plugins: [
[
require.resolve('babel-plugin-transform-flow-enums', { paths: [presetDir] }),
{
getRuntime: (t) =>
t.callExpression(t.identifier('require'), [t.stringLiteral(flowEnumsRuntimePath)]),
},
],
],I checked that this produces Not a blocker. The current approach works in my tests, but this would be less code and would cover enums in every file. |
# Conflicts: # tests/integration/src/loaders/react-native-parser.test.ts
Name the injected babel-plugin-transform-flow-enums instance so Babel doesn't reject it as a duplicate when the project's Babel config already includes the plugin, a common workaround for enums the preset strips.

Part of #1422 (v5 patch).
Summary
On RN 0.81+,
flow-loader(and sogetJsTransformRules) emitted invalid JS, becauseflow-remove-typesleaves Flowcomponent/hook/enum/matchin place. Separately,@react-native/babel-presetdrops Flow enums inbabel-loaderandbabel-swc-loader, so RN'sVirtualViewMode.cast()threw at runtime.flow-enums-runtime, resolved from the project orreact-native, so it works with pnpm.componentlowering follows the project's React version:forwardRefon 18,refas a prop on 19.flow-loadercrashing under webpack.Test plan
tests/integration, presets 0.87/0.88 × rspack/webpack: component, hook, enum, match, class fields, source maps, React 18/19, enums in both Babel loaders,getJsTransformRuleswith a pnpm Flow dependency.rspack-swcconfig in tester-app bundles real RN 0.86.3. It failed before this change onView.js.