Skip to content

Commit 7b4efe4

Browse files
committed
feat(repack)!: enable package exports by default in getResolveOptions
Metro has resolved package exports by default since React Native 0.79, and React Native 0.87+ depends on them, so getResolveOptions now defaults enablePackageExports to true. Pass false to resolve through main fields only. Also fix ReanimatedPlugin's warning filter, which no longer matched the setUpTests message from Reanimated 4's Jest utilities after it gained a [Reanimated] prefix.
1 parent d112450 commit 7b4efe4

8 files changed

Lines changed: 55 additions & 20 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@callstack/repack-plugin-reanimated': patch
3+
---
4+
5+
Fix `ReanimatedPlugin` not hiding the `setUpTests` / `Critical dependency: require function` warning from Reanimated 4's Jest utilities, whose message is now prefixed with `[Reanimated] `.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@callstack/repack': major
3+
---
4+
5+
`getResolveOptions()` now enables package exports by default (`enablePackageExports: true`), matching Metro's default since React Native 0.79. Pass `enablePackageExports: false` to keep resolving through main fields only.

‎packages/plugin-reanimated/src/plugin.ts‎

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import semver, { type SemVer } from 'semver';
44
import type { Compiler as WebpackCompiler } from 'webpack';
55
import { createReanimatedModuleRules } from './rules.js';
66

7+
// Reanimated 4 prefixes the message with `[Reanimated] `
78
const REANIMATED_SETUP_TESTS_WARNING =
8-
/'`setUpTests` is available only in Jest environment\.'/;
9+
/`setUpTests` is available only in Jest environment\./;
910
const WORKLETS_CRITICAL_DEPENDENCY_WARNING =
1011
/Critical dependency: require function is used in a way in which dependencies cannot be statically extracted/;
11-
const WORKLETS_INITIALIZERS_MODULE =
12-
/react-native-(?:worklets|reanimated)[\\/].*initializers(?:\.[cm]?[jt]sx?)?/;
12+
// Modules that call `require` dynamically to load Jest-only dependencies
13+
const WORKLETS_DYNAMIC_REQUIRE_MODULE =
14+
/react-native-(?:worklets|reanimated)[\\/].*(?:initializers|jestUtils)/;
1315

1416
type WarningLike = {
1517
message?: unknown;
@@ -101,7 +103,7 @@ export class ReanimatedPlugin {
101103
return (
102104
REANIMATED_SETUP_TESTS_WARNING.test(warningText) ||
103105
(WORKLETS_CRITICAL_DEPENDENCY_WARNING.test(warningText) &&
104-
WORKLETS_INITIALIZERS_MODULE.test(warningText))
106+
WORKLETS_DYNAMIC_REQUIRE_MODULE.test(warningText))
105107
);
106108
});
107109
}

‎packages/repack/src/utils/__tests__/getResolveOptions.test.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ describe('getResolveOptions', () => {
4242
expect(result.extensions).not.toContain('.android.js');
4343
});
4444

45+
it('should enable package exports by default', () => {
46+
const result = getResolveOptions('ios');
47+
expect(result.exportsFields).toEqual(['exports']);
48+
expect(result.conditionNames).toEqual(['react-native']);
49+
});
50+
51+
it('should disable package exports when enablePackageExports is false', () => {
52+
const result = getResolveOptions('ios', { enablePackageExports: false });
53+
expect(result.exportsFields).toEqual([]);
54+
expect(result.conditionNames).toEqual([]);
55+
});
56+
4557
it('should use actual platform value when provided', () => {
4658
const result = getResolveOptions('ios');
4759
expect(result).toBeDefined();

‎packages/repack/src/utils/getResolveOptions.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface GetResolveOptionsResult {
1515
*/
1616
export interface ResolveOptions {
1717
/**
18-
* Whether to enable Package Exports support. Defaults to `false`.
18+
* Whether to enable Package Exports support. Defaults to `true`, matching Metro.
1919
*/
2020
enablePackageExports?: boolean;
2121
/**
@@ -28,8 +28,8 @@ export interface ResolveOptions {
2828
* Get Webpack's resolve options to properly resolve JavaScript files:
2929
* - resolve platform extensions (e.g. `file.ios.js`)
3030
* - resolve native extensions (e.g. `file.native.js`)
31-
* - optionally use package exports (`exports` field in `package.json`) instead of
32-
* main fields (e.g. `main` or `browser` or `react-native`)
31+
* - use package exports (`exports` field in `package.json`) before main fields
32+
* (e.g. `main` or `browser` or `react-native`), unless disabled
3333
*
3434
* @param platform Target application platform.
3535
* @param options Additional options that can modify resolution behaviour.
@@ -48,7 +48,7 @@ export interface ResolveOptions {
4848
* return {
4949
* resolve: {
5050
* ...Repack.getResolveOptions(platform, {
51-
* enablePackageExports: false,
51+
* enablePackageExports: true,
5252
* preferNativePlatform: true
5353
* }),
5454
* },
@@ -78,7 +78,7 @@ export function getResolveOptions(
7878
) as ResolveOptions | undefined;
7979

8080
const preferNativePlatform = _options?.preferNativePlatform ?? true;
81-
const enablePackageExports = _options?.enablePackageExports ?? false;
81+
const enablePackageExports = _options?.enablePackageExports ?? true;
8282

8383
let extensions = ['.js', '.jsx', '.ts', '.tsx', '.json'];
8484

‎website/src/latest/api/utils/get-resolve-options.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,12 @@ Target application platform (e.g. `ios` or `android`).
2828
### options.enablePackageExports
2929

3030
- Type: `boolean`
31-
- Default: `false`
31+
- Default: `true`
3232

3333
Whether to enable Package Exports support. When enabled, uses the `exports` field in `package.json` instead of main fields.
3434

3535
:::warning
36-
React Native 0.88 requires `enablePackageExports: true` in your Re.Pack resolver configuration. Its `react-native/setup-env` and `react-native/react-private-interface` entry points, as well as `@react-native/asset-utils`, use package exports.
36+
React Native 0.88 requires package exports, so don't set `enablePackageExports: false` there. Its `react-native/setup-env` and `react-native/react-private-interface` entry points, as well as `@react-native/asset-utils`, use package exports.
3737

3838
Enabling package exports can change how existing dependencies resolve. For more details, please refer to the [Module Resolution guide](/docs/features/module-resolution).
3939
:::

‎website/src/latest/docs/features/module-resolution.md‎

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,7 @@ import * as Repack from "@callstack/repack";
2222
export default (env) => {
2323
return {
2424
resolve: {
25-
...Repack.getResolveOptions(env.platform, {
26-
enablePackageExports: true,
27-
}),
25+
...Repack.getResolveOptions(env.platform),
2826
},
2927
};
3028
};
@@ -105,7 +103,7 @@ Main fields are `package.json` properties that point to a package's entry file.
105103

106104
:::
107105

108-
When resolving a package's entry point, Re.Pack checks these fields in `package.json` in order:
106+
When a package has no `exports` field, or [package exports](#package-exports-conditional-exports) are disabled, Re.Pack resolves its entry point by checking these fields in `package.json` in order:
109107

110108
1. `react-native` — React Native-specific entry point
111109
2. `browser` — Browser-compatible entry point
@@ -146,15 +144,15 @@ Modern packages use the `exports` field in `package.json` to define entry points
146144

147145
:::caution
148146

149-
Package exports support is **disabled by default** (`enablePackageExports: false`) to maintain backwards compatibility with existing React Native projects. React Native 0.87 requires it for `@react-native/asset-utils`, and 0.88 also for `react-native/setup-env` and `react-native/react-private-interface`. Enable it explicitly for React Native 0.87 and newer, or whenever your dependencies require it. The configuration templates used by `@callstack/repack-init` enable it.
147+
Package exports support is **enabled by default** (`enablePackageExports: true`), matching Metro's default since React Native 0.79. React Native 0.87 requires it for `@react-native/asset-utils`, and 0.88 also for `react-native/setup-env` and `react-native/react-private-interface`, so only disable it if your React Native version and dependencies don't need it.
150148

151149
:::
152150

153-
### Enabling package exports
151+
### Disabling package exports
154152

155153
```ts
156154
Repack.getResolveOptions({
157-
enablePackageExports: true,
155+
enablePackageExports: false,
158156
});
159157
```
160158

@@ -277,7 +275,7 @@ export default (env) => {
277275

278276
1. **Check the package's `package.json`** — Look at `main`, `react-native`, `browser`, and `exports` fields
279277
2. **Verify platform extensions** — Ensure platform-specific files use correct naming (`.ios.js`, not `.iOS.js`)
280-
3. **Check `enablePackageExports`** — Some modern packages require this to be `true`
278+
3. **Check `enablePackageExports`** — Some modern packages require this to be `true` (the default)
281279

282280
### Platform-specific files not being picked up
283281

@@ -287,7 +285,7 @@ export default (env) => {
287285

288286
### Package exports compatibility issues
289287

290-
When enabling `enablePackageExports`, some packages may resolve differently:
288+
With `enablePackageExports` enabled, some packages may resolve differently than with main fields only:
291289

292290
1. **Compare with Metro** — Test the same import in a Metro-bundled project
293291
2. **Check condition order** — The `react-native` condition should take precedence

‎website/src/latest/docs/migration-guides/repack-v5.mdx‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ Update the Re.Pack plugins you use (`@callstack/repack-plugin-*`) to the same ma
2828

2929
React Native 0.82 removed the legacy architecture, so Re.Pack's native module is now built only as a TurboModule. If your app still sets `newArchEnabled=false`, migrate it to the [New Architecture](https://reactnative.dev/architecture/landing-page) before upgrading.
3030

31+
## Package exports are enabled by default
32+
33+
`getResolveOptions()` now sets `enablePackageExports` to `true` by default, matching Metro's default since React Native 0.79. Configs that already pass `enablePackageExports: true` don't need changes. If your project relies on main-field resolution, opt out explicitly:
34+
35+
```diff
36+
resolve: {
37+
- ...Repack.getResolveOptions(),
38+
+ ...Repack.getResolveOptions({ enablePackageExports: false }),
39+
},
40+
```
41+
42+
See [Module Resolution](/docs/features/module-resolution#package-exports-conditional-exports) for how package exports change resolution.
43+
3144
## Module Federation V1 was removed
3245

3346
`ModuleFederationPluginV1` is no longer available, and `Repack.plugins.ModuleFederationPlugin` now points to [`ModuleFederationPluginV2`](/api/plugins/module-federation-v2). Follow [Migrating from V1](/docs/features/module-federation#migrating-from-v1) to move your configs to Module Federation 2.0.

0 commit comments

Comments
 (0)