[v6] Rework the SWC setup: native Flow support and a modernized getJsTransformRules
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 30/100
- Tipo de issue
- Refactorización
- Claridad
- Bastante claro
- Estado de actividad
- Activo
- Stack tecnológico
- react-native, typescript
- Área
- build-system, tooling
Línea de trabajo
Lee los puntos de entrada actuales getJsTransformRules, getSwcLoaderOptions y getFlowTransformRules, y luego revisa la limitación del parser de Rspack descrita aquí. Usa tests/integration y la cobertura propuesta de tester-app o config-matrix como puntos de partida para la validación. Se considera terminado cuando haya un flujo de Flow v6 acordado, reglas y opciones actualizadas, documentación y cobertura para componentes, hooks, enums e imports no utilizados.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Motivation
Re.Pack's SWC-native pipeline (getJsTransformRules → getSwcLoaderOptions + getFlowTransformRules) strips Flow types in a separate JavaScript pass (flow-remove-types behind @callstack/repack/flow-loader) before handing sources to builtin:swc-loader. SWC can now parse and strip Flow natively (jsc.parser.syntax: "flow", docs) — landed via swc#11685, shipped in @swc/core 1.15.21 (March 2026), with React Native parity fixes continuing through 1.15.46 (current). That makes the extra pass redundant — and it is already broken on modern React Native.
Part of #1414 (Roadmap to V6), which lists "use swc built in flow removal".
The current Flow pass is broken on RN ≥ 0.81
flow-remove-types only erases type annotations. It does not desugar Flow's component / hook syntax or Flow enums — the keywords stay behind, producing invalid JavaScript that SWC then refuses to parse. React Native ships component syntax in core since 0.81 (Libraries/Components/View/View.js:25: component View(), so getJsTransformRules() cannot build RN 0.81+. Reproduced with the workspace versions ([email protected], @swc/[email protected]):
flow-remove-types keeps the component keyword; swc parse of the output:
x Expected ';', '}' or <eof> (View.js:25)
swc one-pass { syntax: 'flow', jsx: true, enums: true, components: true }: OK
This goes unnoticed because nothing in this repo exercises getJsTransformRules — templates/ and all tester apps use @callstack/repack/babel-swc-loader. The Rspack migration guide does document getJsTransformRules + flow-loader as the setup to adopt, though (the Metro guide embeds the babel-swc-loader templates and is unaffected).
The extra pass is also the slowest part of the pipeline
Stripping all 455 .js files in react-native/Libraries (4.6 MB): flow-remove-types 659 ms (strip only, single-threaded JS) vs SWC flow mode 209 ms serial / 59 ms parallel — for strip plus full transform. Dropping the loader also removes a parse → print → source-map round trip per Flow module and the flow-remove-types + hermes-parser install footprint.
What SWC's Flow mode covers
Verified on @swc/[email protected] with { syntax: 'flow', jsx: true, enums: true, components: true }:
- Annotations,
import type,opaque type,declare,export type *— stripped (parity withflow-remove-types). component/hook— desugared correctly (flow-remove-typesemits invalid JS).- Flow enums — transpiled (
flow-remove-typespasses them through verbatim), but not to theflow-enums-runtimerepresentation — see behaviour notes below. enumsandcomponentsare not default — without them these constructs are parse errors.requireDirectivemust stay off to match our currentall: true(with it, files without a@flowpragma get no stripping at all).
Blocker: Rspack does not expose syntax: "flow"
True on every published version — verified on 1.6.0 and 2.0.0-alpha.1 (unknown variant 'flow', expected 'ecmascript' or 'typescript'), and latest 2.1.6 / main has no flow variant in SwcLoaderParserConfig either. Bumping to Rspack 2 does not fix it. Rspack main is already on swc_core = "72.0.0"; the gap is a Cargo feature: SWC gates the Flow parser behind base_flow (swc_core → swc/flow → swc_ecma_parser/flow), and rspack_loader_swc doesn't enable it. The upstream fix is one feature flag, the corresponding SwcLoaderParserConfig type, and a detectSyntax mapping decision for .flow / .js.flow. Precedent for this kind of ask: rspack#13843 (swc_core bump + exposing jsc.preserveSymlinks) was accepted and shipped.
Fallback if upstream is slow: route Flow-typed modules through a Re.Pack loader backed by standalone @swc/core, which has the feature compiled in. babelSwcLoader's lazyGetSwc already resolves rspack.experiments.swc → @rspack/core → @swc/core, so the plumbing exists. Costs the JS↔Rust boundary again, but stays single-pass and works on webpack too.
Behaviour differences vs Babel
- Unused value imports are elided by default. SWC's flow mode applies TypeScript-style import elision (
import Unused from './u'; console.log(1)→console.log(1)).jsc.transform.verbatimModuleSyntax: truefixes this — verified it preserves unused value imports while still strippingimport typeandtypespecifiers. Set it and pin with a regression test. - Flow enums don't use
flow-enums-runtime. SWC emits a TS-style object IIFE. Member access matches Flow semantics, but the runtime API (.members(),.cast(),.isValid(),.getName()) doesn't exist on the result. RN core doesn't call those methods today; needs a documented caveat (and a check when bumping RN). exportDefaultFromis unavailable undersyntax: "flow"(export v from './v'→ parse error), whilegetParserOptionsenables it for all.js(RN's preset includes@babel/plugin-proposal-export-default-from). Soflowcannot blanket-replaceecmascriptfor.js— keep it scoped to Flow-typed modules until SWC supports the combination.
Other issues in getSwcLoaderOptions / getJsTransformRules
Independent of Flow, worth fixing in the same pass:
developmentis tied to the JSX runtime, notmode.getJSCTransformOptionssetsdevelopment: jsxRuntime === 'classic', so with the defaultautomaticruntime dev builds always getjsxinstead ofjsxDEV(verified) — losing__source/__self, accurate component stacks, and "open in editor". RN's preset addsjsx-source/jsx-selfwheneverdev. Should followmode.- The six-branch
oneOfcollapses under Rspack 2.detectSyntax: 'auto'(new in 2.0.0) infers the parser from the extension, leaving only the sourcemaps-off-for-node_modulessplit;tsRules/tsxRulesare byte-identical today anyway. Unrecognized extensions map to{ syntax: 'typescript', tsx: true }, so.flowneeds an explicit branch either way. env.targets: { node: 24 }is a sentinel, not a target ("assume everything supported, re-add viaenv.include"). It works but drifts silently, and Rspack 2 derives loader targets from the top-leveltargetwhen unset. Re-deriveenv.include(16 entries) from the current RN preset and write down each inclusion/omission — e.g.transform-react-display-nameis missing from both SWC paths, and the preset's regenerator-gated trio (optional-catch-binding,nullish-coalescing,for-of) is dev+Hermes-only, so omitting it may be correct but should be a written decision.lazyImportsdefaults tofalse, while RN's preset defaultslazyto itslazy-importsallowlist.isModuleis never set (babelSwcLoadersets it from Babel'ssourceType;isModule: 'unknown'is probably right here).getSwcParserConfig(babelSwcLoader) andgetParserOptions(getSwcLoaderOptions) are near-duplicates with different answers (exportDefaultFrom). Fold into one shared helper.getCodegenTransformRuleskeeps its Babel pass —@react-native/babel-plugin-codegenhas no SWC equivalent — but the "must run before Flow stripping" ordering constraint deserves a re-check once SWC parses Flow natively.
babel-swc-loader
Stays as-is — it is the default in templates/ and every tester app, and it is correct by construction (it reads the project's real Babel config and only offloads transforms it can prove equivalent). Follow-up once Flow support is available: teach swc.ts to map transform-flow-strip-types / transform-flow-enums / syntax-hermes-parser to jsc.parser.syntax: 'flow' (+ enums, components), so RN core files go through SWC instead of falling back to Babel — the biggest remaining Babel fallback for a stock RN app.
Scope
Upstream
- Rspack: file the issue/PR enabling
base_flowinrspack_loader_swc, exposing the flow parser options inSwcLoaderParserConfig, and deciding thedetectSyntaxmapping for.flow - SWC: file the issue for
exportDefaultFromundersyntax: "flow"
Core
- Switch
getFlowTransformRulesfromflow-loaderto SWC-native Flow (or the@swc/core-backed fallback loader), keeping theFLOW_TYPED_MODULESinclude/exclude surface; setverbatimModuleSyntax: true - Decide the fate of
@callstack/repack/flow-loader(public export) — deprecate as escape hatch or drop in v6 - Rewrite
getJsTransformRulesondetectSyntax: 'auto', collapsing theoneOf - Drive
jsc.transform.react.developmentfrommode - Re-derive
env.includefrom the current RN preset; alignlazyImports/isModuledefaults - Fold
getSwcParserConfigandgetParserOptionsinto one helper - Drop the
flow-remove-typesdependency once nothing uses it
v5 patch (independent of v6)
- Stop
getJsTransformRulesemitting invalid JS forcomponent/hook/ enums on RN ≥ 0.81 — either the SWC path orbabel-plugin-syntax-hermes-parser+babel-plugin-transform-flow-enumsinflow-loader
Apps, tests, docs
- Add a tester-app variant or config-matrix entry that actually builds with
getJsTransformRules— this class of bug is invisible today -
tests/integrationcoverage forcomponent/hook/ Flow enums in anode_modulesdependency; regression test pinning unused-import preservation - Update
flow-loader,get-flow-transform-rules,get-swc-loader-options,get-js-transform-rulesdocs and the Rspack migration guide; note the minimum Rspack version in the v5 → v6 migration guide
Open questions
- Wait on upstream Rspack, or ship the
@swc/core-backed loader first (works today, keeps webpack) and switch tobuiltin:swc-loaderwhen the feature flag lands? - Does
getJsTransformRulesremain a second-class alternative tobabel-swc-loader, or does v6 make it the default intemplates/? #1414 targets Rspack 2+ as a minimum, which makes it viable as a default for the first time — but only if it becomes the path we actually test.
- Lenguaje dominante
- TypeScript
- Estrellas
- 1.9k
- Forks
- 167
- Merge medio
- 4 d 28 min
- PR fusionados (30 d)
- 8
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Sin plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de callstack/repack
-
React Native 0.88.x supportAbiertostatus:new type:bug
Dificultad 3/5 1-2 días Aptitud para principiantes 48/100
callstack/repack#1474 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 78/100
callstack/repack#1464 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
json as string in JS bundleAbierto
Dificultad 5/5 Más de una semana Aptitud para principiantes 35/100
callstack/repack#1461 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 3/5 1-2 días Aptitud para principiantes 78/100
callstack/repack#1447 · 3 comentarios ·
Los mantenedores suelen responder en 1 día
-
area:repack type:feature
Dificultad 5/5 Más de una semana Aptitud para principiantes 42/100
callstack/repack#1423 · 1 comentario ·
Los mantenedores suelen responder en 1 día
Todos los issues de callstack/repack
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
Los mantenedores suelen responder en 1 día
-
bug:new
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
callstackincubator/simlock#350 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
openwatersio/maritime-zones#33 ·
Los mantenedores suelen responder en 1 día
-
Booking email verification fails for plus aliases with impersonation protection enabledPosiblemente ocupada @kankadev la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
calcom/cal.diy#30293 · 1 comentario ·
Los mantenedores suelen responder en 5 días
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
AOSSIE-Org/DebateAI#611 ·
Los mantenedores suelen responder en 3 días