expo-router 1.7.6 → 1.7.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/babel.js CHANGED
@@ -94,6 +94,19 @@ function getExpoRouterAppRoot(projectRoot) {
94
94
  }
95
95
  const routerEntry = resolveFrom.silent(projectRoot, "expo-router/entry");
96
96
 
97
+ // It doesn't matter if the app folder exists.
98
+ const appFolder = getExpoRouterAbsoluteAppRoot(projectRoot);
99
+ const appRoot = nodePath.relative(nodePath.dirname(routerEntry), appFolder);
100
+ debug("routerEntry", routerEntry, appFolder, appRoot);
101
+
102
+ process.env.EXPO_ROUTER_APP_ROOT_2 = appRoot;
103
+ return appRoot;
104
+ }
105
+
106
+ function getExpoRouterAbsoluteAppRoot(projectRoot) {
107
+ if (process.env.EXPO_ROUTER_ABS_APP_ROOT) {
108
+ return process.env.EXPO_ROUTER_ABS_APP_ROOT;
109
+ }
97
110
  const { exp } = getConfigMemo(projectRoot);
98
111
  const customSrc =
99
112
  exp.extra?.router?.unstable_src || getRouterDirectory(projectRoot);
@@ -102,10 +115,10 @@ function getExpoRouterAppRoot(projectRoot) {
102
115
  const appFolder = isAbsolute
103
116
  ? customSrc
104
117
  : nodePath.join(projectRoot, customSrc);
105
- const appRoot = nodePath.relative(nodePath.dirname(routerEntry), appFolder);
106
- debug("routerEntry", routerEntry, appFolder, appRoot);
118
+ const appRoot = appFolder;
119
+ debug("absolute router entry", appFolder, appRoot);
107
120
 
108
- process.env.EXPO_ROUTER_APP_ROOT_2 = appRoot;
121
+ process.env.EXPO_ROUTER_ABS_APP_ROOT = appFolder;
109
122
  return appRoot;
110
123
  }
111
124
  // TODO: Strip the function `generateStaticParams` when bundling for node.js environments.
@@ -161,13 +174,10 @@ module.exports = function (api) {
161
174
  !parent.parentPath.isAssignmentExpression()
162
175
  ) {
163
176
  parent.replaceWith(t.stringLiteral(projectRoot));
164
- return;
165
- }
166
-
167
- // Enable static rendering
168
- // TODO: Use a serializer or something to ensure this changes without
169
- // needing to clear the cache.
170
- if (
177
+ } else if (
178
+ // Enable static rendering
179
+ // TODO: Use a serializer or something to ensure this changes without
180
+ // needing to clear the cache.
171
181
  t.isIdentifier(parent.node.property, {
172
182
  name: "EXPO_PUBLIC_USE_STATIC",
173
183
  }) &&
@@ -177,12 +187,9 @@ module.exports = function (api) {
177
187
  parent.replaceWith(
178
188
  t.stringLiteral(process.env.EXPO_PUBLIC_USE_STATIC)
179
189
  );
180
- return;
181
- }
182
-
183
- // Surfaces the `app.json` (config) as an environment variable which is then parsed by
184
- // `expo-constants` https://docs.expo.dev/versions/latest/sdk/constants/
185
- if (
190
+ } else if (
191
+ // Surfaces the `app.json` (config) as an environment variable which is then parsed by
192
+ // `expo-constants` https://docs.expo.dev/versions/latest/sdk/constants/
186
193
  t.isIdentifier(parent.node.property, {
187
194
  name: "APP_MANIFEST",
188
195
  }) &&
@@ -190,11 +197,31 @@ module.exports = function (api) {
190
197
  ) {
191
198
  const manifest = getExpoAppManifest(projectRoot);
192
199
  parent.replaceWith(t.stringLiteral(manifest));
193
- return;
194
- }
195
-
196
- // Expose the app route import mode.
197
- if (
200
+ } else if (
201
+ process.env.NODE_ENV !== "test" &&
202
+ t.isIdentifier(parent.node.property, {
203
+ name: "EXPO_ROUTER_ABS_APP_ROOT",
204
+ }) &&
205
+ !parent.parentPath.isAssignmentExpression()
206
+ ) {
207
+ parent.replaceWith(
208
+ t.stringLiteral(getExpoRouterAbsoluteAppRoot(projectRoot))
209
+ );
210
+ } else if (
211
+ // Skip loading the app root in tests.
212
+ // This is handled by the testing-library utils
213
+ process.env.NODE_ENV !== "test" &&
214
+ t.isIdentifier(parent.node.property, {
215
+ name: "EXPO_ROUTER_APP_ROOT",
216
+ }) &&
217
+ !parent.parentPath.isAssignmentExpression()
218
+ ) {
219
+ parent.replaceWith(
220
+ // This is defined in Expo CLI when using Metro. It points to the relative path for the project app directory.
221
+ t.stringLiteral(getExpoRouterAppRoot(projectRoot))
222
+ );
223
+ } else if (
224
+ // Expose the app route import mode.
198
225
  platform &&
199
226
  t.isIdentifier(parent.node.property, {
200
227
  name: "EXPO_ROUTER_IMPORT_MODE_" + platform.toUpperCase(),
@@ -204,31 +231,7 @@ module.exports = function (api) {
204
231
  parent.replaceWith(
205
232
  t.stringLiteral(getExpoRouterImportMode(projectRoot, platform))
206
233
  );
207
- return;
208
234
  }
209
-
210
- if (
211
- !t.isIdentifier(parent.node.property, {
212
- name: "EXPO_ROUTER_APP_ROOT",
213
- })
214
- ) {
215
- return;
216
- }
217
-
218
- if (parent.parentPath.isAssignmentExpression()) {
219
- return;
220
- }
221
-
222
- // Skip loading the app root in tests.
223
- // This is handled by the testing-library utils
224
- if (process.env.NODE_ENV === "test") {
225
- return;
226
- }
227
-
228
- parent.replaceWith(
229
- // This is defined in Expo CLI when using Metro. It points to the relative path for the project app directory.
230
- t.stringLiteral(getExpoRouterAppRoot(projectRoot))
231
- );
232
235
  },
233
236
  },
234
237
  };
@@ -8,6 +8,7 @@ export declare function getNameFromFilePath(name: string): string;
8
8
  export declare function getContextKey(name: string): string;
9
9
  /** Remove `.js`, `.ts`, `.jsx`, `.tsx` */
10
10
  export declare function removeSupportedExtensions(name: string): string;
11
+ export declare function removeFileSystemDots(filePath: string): string;
11
12
  export declare function stripGroupSegmentsFromPath(path: string): string;
12
13
  export declare function stripInvisibleSegmentsFromPath(path: string): string;
13
14
  //# sourceMappingURL=matchers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../src/matchers.tsx"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIjE;AAED,kCAAkC;AAClC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED,+BAA+B;AAC/B,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,0CAA0C;AAC1C,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAOD,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE"}
1
+ {"version":3,"file":"matchers.d.ts","sourceRoot":"","sources":["../src/matchers.tsx"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIjE;AAED,kCAAkC;AAClC,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED,+BAA+B;AAC/B,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQlD;AAED,0CAA0C;AAC1C,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9D;AAGD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU/D;AAED,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE"}
@@ -1,3 +1,4 @@
1
1
  /** Middleware for creating an entry file in the project. */
2
2
  export declare function createEntryFileAsync(): Promise<Response> | undefined;
3
+ export declare function getAbsolutePath(): string;
3
4
  //# sourceMappingURL=createEntryFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"createEntryFile.d.ts","sourceRoot":"","sources":["../../src/onboard/createEntryFile.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,wBAAgB,oBAAoB,kCAuBnC"}
1
+ {"version":3,"file":"createEntryFile.d.ts","sourceRoot":"","sources":["../../src/onboard/createEntryFile.ts"],"names":[],"mappings":"AAEA,4DAA4D;AAC5D,wBAAgB,oBAAoB,kCAkBnC;AAED,wBAAgB,eAAe,WAE9B"}
@@ -1 +1 @@
1
- {"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAIL,SAAS,EAGV,MAAM,SAAS,CAAC;AAOjB,MAAM,MAAM,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACxD;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAGnB,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB,CAAC;AA8DF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AA6BD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,kIAuE1D;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC;;sCA0B5C"}
1
+ {"version":3,"file":"useScreens.d.ts","sourceRoot":"","sources":["../src/useScreens.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAIL,SAAS,EAGV,MAAM,SAAS,CAAC;AAOjB,MAAM,MAAM,WAAW,CACrB,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,IACxD;IACF,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KAAE,CAAC;IACvC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAGnB,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB,CAAC;AA8DF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAUxE;AAsCD,mFAAmF;AACnF,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,SAAS,kIAuE1D;AAED,oGAAoG;AACpG,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC;;sCA0B5C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-router",
3
- "version": "1.7.6",
3
+ "version": "1.7.7",
4
4
  "main": "src/index.tsx",
5
5
  "types": "build/index.d.ts",
6
6
  "files": [
@@ -104,12 +104,12 @@
104
104
  },
105
105
  "dependencies": {
106
106
  "@bacons/react-views": "^1.1.3",
107
- "@expo/metro-runtime": "2.1.5",
107
+ "@expo/metro-runtime": "2.1.6",
108
108
  "@radix-ui/react-slot": "1.0.1",
109
109
  "@react-navigation/bottom-tabs": "~6.5.7",
110
110
  "@react-navigation/native": "~6.1.6",
111
111
  "@react-navigation/native-stack": "~6.9.12",
112
- "expo-head": "0.0.7",
112
+ "expo-head": "0.0.8",
113
113
  "expo-splash-screen": "*",
114
114
  "query-string": "7.1.3",
115
115
  "react-helmet-async": "^1.3.0",
package/src/ExpoRoot.tsx CHANGED
@@ -66,9 +66,14 @@ function ContextNavigator({
66
66
  const store = useInitializeExpoRouter(context, initialLocation);
67
67
 
68
68
  if (store.shouldShowTutorial()) {
69
- const Tutorial = require("./onboard/Tutorial").Tutorial;
70
69
  SplashScreen.hideAsync();
71
- return <Tutorial />;
70
+ if (process.env.NODE_ENV === "development") {
71
+ const Tutorial = require("./onboard/Tutorial").Tutorial;
72
+ return <Tutorial />;
73
+ } else {
74
+ // Ensure tutorial styles are stripped in production.
75
+ return null;
76
+ }
72
77
  }
73
78
 
74
79
  const Component = store.rootComponent;
package/src/matchers.tsx CHANGED
@@ -35,7 +35,7 @@ export function removeSupportedExtensions(name: string): string {
35
35
  }
36
36
 
37
37
  // Remove any amount of `./` and `../` from the start of the string
38
- function removeFileSystemDots(filePath: string): string {
38
+ export function removeFileSystemDots(filePath: string): string {
39
39
  return filePath.replace(/^(?:\.\.?\/)+/g, "");
40
40
  }
41
41
 
@@ -79,7 +79,7 @@ export function Tutorial() {
79
79
  }
80
80
 
81
81
  function getRootDir() {
82
- const dir = process.env.EXPO_ROUTER_APP_ROOT!;
82
+ const dir = process.env.EXPO_ROUTER_ABS_APP_ROOT!;
83
83
  if (dir.match(/\/src\/app$/)) {
84
84
  return "src/app";
85
85
  } else if (dir.match(/\/app$/)) {
@@ -141,7 +141,8 @@ const styles = StyleSheet.create({
141
141
  flex: 1,
142
142
  backgroundImage:
143
143
  "radial-gradient(circle at 1px 1px, rgba(255,255,255,0.15) 1px, transparent 0)",
144
- backgroundPosition: "-3px -3px",
144
+ backgroundPositionX: -3,
145
+ backgroundPositionY: -3,
145
146
  backgroundSize: "40px 40px",
146
147
  },
147
148
  safeArea: {
@@ -16,16 +16,15 @@ export function createEntryFileAsync() {
16
16
  // Legacy
17
17
  path: "./app/index.js",
18
18
  // New
19
- absolutePath:
20
- process.env.EXPO_PROJECT_ROOT +
21
- "/" +
22
- process.env.EXPO_ROUTER_APP_ROOT +
23
- "/" +
24
- "./index.js",
19
+ absolutePath: getAbsolutePath(),
25
20
  }),
26
21
  });
27
22
  }
28
23
 
24
+ export function getAbsolutePath() {
25
+ return process.env.EXPO_ROUTER_ABS_APP_ROOT + "/index.js";
26
+ }
27
+
29
28
  const TEMPLATE = `import { StyleSheet, Text, View } from "react-native";
30
29
 
31
30
  export default function Page() {
@@ -118,6 +118,15 @@ function fromImport({ ErrorBoundary, ...component }: LoadedRoute) {
118
118
  }),
119
119
  };
120
120
  }
121
+ if (process.env.NODE_ENV !== "production") {
122
+ if (
123
+ typeof component.default === "object" &&
124
+ component.default &&
125
+ Object.keys(component.default).length === 0
126
+ ) {
127
+ return { default: EmptyRoute };
128
+ }
129
+ }
121
130
  return { default: component.default || EmptyRoute };
122
131
  }
123
132