Skip to content

fix(babel): normalize resolved paths to POSIX so Windows rewrites work#390

Open
YevheniiKotyrlo wants to merge 1 commit into
nativewind:mainfrom
YevheniiKotyrlo:fix/babel-windows-posix-paths
Open

fix(babel): normalize resolved paths to POSIX so Windows rewrites work#390
YevheniiKotyrlo wants to merge 1 commit into
nativewind:mainfrom
YevheniiKotyrlo:fix/babel-windows-posix-paths

Conversation

@YevheniiKotyrlo

Copy link
Copy Markdown
Contributor

Summary

The babel import plugin's relative-import rewriting silently no-ops on Windows. parseReactNativeSource / parseReactNativeWebSource resolve a relative source against the file being transformed and then match the result against forward-slash literals:

source = resolve(dirname(filename), source);
const internalPath = source.split("react-native/Libraries/Components/")[1];

path.resolve returns backslash-separated paths on Windows, so .split("react-native/Libraries/Components/") (and the react-native-web/dist split) never matches — internalPath is undefined, the function bails, and the import is left un-rewritten. The plugin's other cases (bare react-native / react-native-web specifiers) are plain string matches and are unaffected, so only relative imports break, and only on Windows.

This surfaces as three tests failing on Windows while green on the Linux/macOS CI:

  • src/__tests__/babel/react-native.test.ts7. import View from '../View/View';
  • src/__tests__/babel/react-native-web.test.ts6. import View from '../View';
  • src/__tests__/babel/react-native-web.test.ts17. const View = _interopRequireDefault(require('../View'));

Fix

Normalize the resolved path to POSIX separators before the forward-slash matching, via a small shared helper:

export function resolvePosix(...segments: string[]): string {
  return resolve(...segments).replace(/\\/g, "/");
}

parseReactNativeSource and parseReactNativeWebSource now call resolvePosix instead of resolve. The resolve semantics are unchanged — each keeps its own base (dirname(filename) vs filename); only the separator is normalized.

import-plugin.ts's isFromThisModule is intentionally left on path.resolve: it compares two OS-native absolute paths (state.filename.startsWith(thisModuleDist)), so both sides share the platform separator and it already works — normalizing only one side would break it.

Test plan

  • The three previously-failing relative-import cases now pass on Windows and remain green on POSIX.
  • New src/__tests__/babel/helpers.test.ts asserts resolvePosix never returns a backslash and collapses .. like path.resolve — a platform-independent guard of the invariant (the e2e cases only exercise the Windows path on a Windows runner).
  • yarn test (full suite green), yarn typecheck, yarn eslint, and prettier --check all pass.

The import plugin's relative-import handlers resolve a source against the file
being transformed and then match the result against forward-slash literals
(`react-native/Libraries/Components/`, `react-native-web/dist`). path.resolve
returns backslash-separated paths on Windows, so those splits never match and
the import is left un-rewritten. Only relative imports break, and only on
Windows -- bare specifiers are plain string matches; the failing cases were
green on the Linux/macOS CI.

Add a `resolvePosix` helper (resolve + normalize \ -> /) and use it in
parseReactNativeSource / parseReactNativeWebSource. Resolve semantics are
unchanged; only the separator is normalized. import-plugin's isFromThisModule
stays on path.resolve -- it compares two OS-native paths, so it already works.

Adds a helpers unit test asserting the POSIX invariant.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant