@expo/cli 0.22.8 → 0.22.10

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.
Files changed (58) hide show
  1. package/build/bin/cli +1 -1
  2. package/build/src/api/rest/client.js +2 -0
  3. package/build/src/api/rest/client.js.map +1 -1
  4. package/build/src/export/embed/exportEmbedAsync.js +3 -3
  5. package/build/src/export/embed/exportEmbedAsync.js.map +1 -1
  6. package/build/src/export/embed/exportServer.js +13 -9
  7. package/build/src/export/embed/exportServer.js.map +1 -1
  8. package/build/src/export/embed/index.js +4 -0
  9. package/build/src/export/embed/index.js.map +1 -1
  10. package/build/src/export/embed/resolveOptions.js +2 -1
  11. package/build/src/export/embed/resolveOptions.js.map +1 -1
  12. package/build/src/export/embed/xcodeCompilerLogger.js +1 -0
  13. package/build/src/export/embed/xcodeCompilerLogger.js.map +1 -1
  14. package/build/src/export/exportApp.js +27 -12
  15. package/build/src/export/exportApp.js.map +1 -1
  16. package/build/src/export/exportStaticAsync.js +18 -2
  17. package/build/src/export/exportStaticAsync.js.map +1 -1
  18. package/build/src/export/publicFolder.js +6 -1
  19. package/build/src/export/publicFolder.js.map +1 -1
  20. package/build/src/export/saveAssets.js +1 -1
  21. package/build/src/export/saveAssets.js.map +1 -1
  22. package/build/src/install/index.js +1 -0
  23. package/build/src/install/index.js.map +1 -1
  24. package/build/src/install/installAsync.js +2 -1
  25. package/build/src/install/installAsync.js.map +1 -1
  26. package/build/src/install/installExpoPackage.js +14 -6
  27. package/build/src/install/installExpoPackage.js.map +1 -1
  28. package/build/src/install/resolveOptions.js +2 -0
  29. package/build/src/install/resolveOptions.js.map +1 -1
  30. package/build/src/serve/serveAsync.js +4 -2
  31. package/build/src/serve/serveAsync.js.map +1 -1
  32. package/build/src/start/doctor/dependencies/getVersionedPackages.js +4 -0
  33. package/build/src/start/doctor/dependencies/getVersionedPackages.js.map +1 -1
  34. package/build/src/start/server/getStaticRenderFunctions.js +2 -1
  35. package/build/src/start/server/getStaticRenderFunctions.js.map +1 -1
  36. package/build/src/start/server/metro/MetroBundlerDevServer.js +105 -55
  37. package/build/src/start/server/metro/MetroBundlerDevServer.js.map +1 -1
  38. package/build/src/start/server/metro/createJResolver.js +15 -5
  39. package/build/src/start/server/metro/createJResolver.js.map +1 -1
  40. package/build/src/start/server/metro/createServerComponentsMiddleware.js +28 -4
  41. package/build/src/start/server/metro/createServerComponentsMiddleware.js.map +1 -1
  42. package/build/src/start/server/metro/metroErrorInterface.js +5 -1
  43. package/build/src/start/server/metro/metroErrorInterface.js.map +1 -1
  44. package/build/src/start/server/metro/withMetroMultiPlatform.js +2 -1
  45. package/build/src/start/server/metro/withMetroMultiPlatform.js.map +1 -1
  46. package/build/src/start/server/middleware/ManifestMiddleware.js +6 -3
  47. package/build/src/start/server/middleware/ManifestMiddleware.js.map +1 -1
  48. package/build/src/start/server/middleware/metroOptions.js +1 -1
  49. package/build/src/start/server/middleware/metroOptions.js.map +1 -1
  50. package/build/src/start/startAsync.js +1 -1
  51. package/build/src/start/startAsync.js.map +1 -1
  52. package/build/src/utils/env.js +9 -0
  53. package/build/src/utils/env.js.map +1 -1
  54. package/build/src/utils/ip.js +8 -1
  55. package/build/src/utils/ip.js.map +1 -1
  56. package/build/src/utils/telemetry/clients/FetchClient.js +1 -1
  57. package/build/src/utils/telemetry/utils/context.js +1 -1
  58. package/package.json +16 -16
@@ -265,12 +265,13 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
265
265
  }
266
266
  async getServerManifestAsync() {
267
267
  // NOTE: This could probably be folded back into `renderStaticContent` when expo-asset and font support RSC.
268
- const { getBuildTimeServerManifestAsync } = await this.ssrLoadModule("expo-router/build/static/getServerManifest.js", {
268
+ const { getBuildTimeServerManifestAsync , getManifest } = await this.ssrLoadModule("expo-router/build/static/getServerManifest.js", {
269
269
  // Only use react-server environment when the routes are using react-server rendering by default.
270
270
  environment: this.isReactServerRoutesEnabled ? "react-server" : "node"
271
271
  });
272
272
  return {
273
- serverManifest: await getBuildTimeServerManifestAsync()
273
+ serverManifest: await getBuildTimeServerManifestAsync(),
274
+ htmlManifest: await getManifest()
274
275
  };
275
276
  }
276
277
  async getStaticRenderFunctionAsync() {
@@ -375,7 +376,8 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
375
376
  instanceMetroOptions = {};
376
377
  ssrLoadModule = async (filePath, specificOptions = {}, extras = {})=>{
377
378
  const res = await this.ssrLoadModuleContents(filePath, specificOptions);
378
- if (extras.hot && this.instanceMetroOptions.isExporting !== true) {
379
+ if (// TODO: hot should be a callback function for invalidating the related SSR module.
380
+ extras.hot && this.instanceMetroOptions.isExporting !== true) {
379
381
  // Register SSR HMR
380
382
  const serverRoot = (0, _paths().getMetroServerRoot)(this.projectRoot);
381
383
  const relativePath = _path().default.relative(serverRoot, res.filename);
@@ -524,52 +526,56 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
524
526
  return this.legacySinglePageExportBundleAsync(options, extraOptions);
525
527
  }
526
528
  async singlePageReactServerComponentExportAsync(options, files, extraOptions = {}) {
529
+ const getReactServerReferences = (artifacts)=>{
530
+ // Get the React server action boundaries from the client bundle.
531
+ return unique(artifacts.filter((a)=>a.type === "js").map((artifact)=>{
532
+ var ref;
533
+ return (ref = artifact.metadata.reactServerReferences) == null ? void 0 : ref.map((ref)=>(0, _createServerComponentsMiddleware.fileURLToFilePath)(ref));
534
+ })// TODO: Segment by module for splitting.
535
+ .flat().filter(Boolean));
536
+ };
527
537
  // NOTE(EvanBacon): This will not support any code elimination since it's a static pass.
528
538
  let { reactClientReferences: clientBoundaries , reactServerReferences: serverActionReferencesInServer , cssModules , } = await this.rscRenderer.getExpoRouterClientReferencesAsync({
529
539
  platform: options.platform,
530
540
  domRoot: options.domRoot
531
541
  }, files);
532
542
  // TODO: The output keys should be in production format or use a lookup manifest.
533
- debug("Evaluated client boundaries:", clientBoundaries);
534
- // Run metro bundler and create the JS bundles/source maps.
535
- let bundle = await this.legacySinglePageExportBundleAsync({
536
- ...options,
537
- clientBoundaries
538
- }, extraOptions);
539
- // Get the React server action boundaries from the client bundle.
540
- const reactServerReferences = bundle.artifacts.filter((a)=>a.type === "js").map((artifact)=>{
541
- var ref;
542
- return (ref = artifact.metadata.reactServerReferences) == null ? void 0 : ref.map((ref)=>(0, _createServerComponentsMiddleware.fileURLToFilePath)(ref));
543
- })// TODO: Segment by module for splitting.
544
- .flat().filter(Boolean);
545
- if (!reactServerReferences) {
546
- // Issue with babel plugin / metro-config.
547
- throw new Error("Static server action references were not returned from the Metro client bundle");
548
- }
549
- debug("React server action boundaries from client:", reactServerReferences);
550
- // When we export the server actions that were imported from the client, we may need to re-bundle the client with the new client boundaries.
551
- const { clientBoundaries: nestedClientBoundaries } = await this.rscRenderer.exportServerActionsAsync({
552
- platform: options.platform,
553
- domRoot: options.domRoot,
554
- entryPoints: [
555
- ...serverActionReferencesInServer,
556
- ...reactServerReferences
557
- ]
558
- }, files);
559
- // TODO: Check against all modules in the initial client bundles.
560
- const hasUniqueClientBoundaries = nestedClientBoundaries.some((boundary)=>!clientBoundaries.includes(boundary));
561
- if (hasUniqueClientBoundaries) {
562
- debug("Re-bundling client with nested client boundaries:", nestedClientBoundaries);
563
- clientBoundaries = [
564
- ...new Set(clientBoundaries.concat(nestedClientBoundaries))
565
- ];
566
- // Re-bundle the client with the new client boundaries that only exist in server actions that were imported from the client.
543
+ const processClientBoundaries = async (reactServerReferences)=>{
544
+ debug("Evaluated client boundaries:", clientBoundaries);
567
545
  // Run metro bundler and create the JS bundles/source maps.
568
- bundle = await this.legacySinglePageExportBundleAsync({
546
+ const bundle = await this.legacySinglePageExportBundleAsync({
569
547
  ...options,
570
548
  clientBoundaries
571
549
  }, extraOptions);
572
- }
550
+ // Get the React server action boundaries from the client bundle.
551
+ const newReactServerReferences = getReactServerReferences(bundle.artifacts);
552
+ if (!newReactServerReferences) {
553
+ // Possible issue with babel plugin / metro-config.
554
+ throw new Error("Static server action references were not returned from the Metro client bundle");
555
+ }
556
+ debug("React server action boundaries from client:", newReactServerReferences);
557
+ const allKnownReactServerReferences = unique([
558
+ ...reactServerReferences,
559
+ ...newReactServerReferences,
560
+ ]);
561
+ // When we export the server actions that were imported from the client, we may need to re-bundle the client with the new client boundaries.
562
+ const { clientBoundaries: nestedClientBoundaries } = await this.rscRenderer.exportServerActionsAsync({
563
+ platform: options.platform,
564
+ domRoot: options.domRoot,
565
+ entryPoints: allKnownReactServerReferences
566
+ }, files);
567
+ // TODO: Check against all modules in the initial client bundles.
568
+ const hasUniqueClientBoundaries = nestedClientBoundaries.some((boundary)=>!clientBoundaries.includes(boundary));
569
+ if (!hasUniqueClientBoundaries) {
570
+ return bundle;
571
+ }
572
+ debug("Re-bundling client with nested client boundaries:", nestedClientBoundaries);
573
+ clientBoundaries = unique(clientBoundaries.concat(nestedClientBoundaries));
574
+ // Re-bundle the client with the new client boundaries that only exist in server actions that were imported from the client.
575
+ // Run metro bundler and create the JS bundles/source maps.
576
+ return processClientBoundaries(allKnownReactServerReferences);
577
+ };
578
+ const bundle = await processClientBoundaries(serverActionReferencesInServer);
573
579
  // Inject the global CSS that was imported during the server render.
574
580
  bundle.artifacts.push(...cssModules);
575
581
  const serverRoot = (0, _paths().getMetroServerRoot)(this.projectRoot);
@@ -670,7 +676,7 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
670
676
  }
671
677
  rscRenderer = null;
672
678
  async startImplementationAsync(options) {
673
- var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7;
679
+ var ref, ref1, ref2, ref3, ref4, ref5, ref6, ref7, ref8, ref9, ref10;
674
680
  options.port = await this.resolvePortAsync(options);
675
681
  this.urlCreator = this.getUrlCreator(options);
676
682
  const config = (0, _config().getConfig)(this.projectRoot, {
@@ -693,8 +699,14 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
693
699
  const reactCompiler = !!((ref7 = exp.experiments) == null ? void 0 : ref7.reactCompiler);
694
700
  const appDir = _path().default.join(this.projectRoot, routerRoot);
695
701
  const mode = options.mode ?? "development";
696
- if (isReactServerComponentsEnabled && useServerRendering) {
697
- throw new _errors.CommandError(`Experimental server component support does not support 'web.output: ${exp.web.output}' yet. Use 'web.output: "single"' during the experimental phase.`);
702
+ if (isReactServerComponentsEnabled && ((ref8 = exp.web) == null ? void 0 : ref8.output) === "static") {
703
+ throw new _errors.CommandError(`Experimental server component support does not support 'web.output: ${exp.web.output}' yet. Use 'web.output: "server"' during the experimental phase.`);
704
+ }
705
+ // Error early about the window.location polyfill when React Server Components are enabled.
706
+ if (isReactServerComponentsEnabled && (exp == null ? void 0 : (ref9 = exp.extra) == null ? void 0 : (ref10 = ref9.router) == null ? void 0 : ref10.origin) === false) {
707
+ const configPath = config.dynamicConfigPath ?? config.staticConfigPath ?? "/app.json";
708
+ const configFileName = _path().default.basename(configPath);
709
+ throw new _errors.CommandError(`The Expo Router "origin" property in the Expo config (${configFileName}) cannot be "false" when React Server Components is enabled. Remove it from the ${configFileName} file and try again.`);
698
710
  }
699
711
  const instanceMetroOptions = {
700
712
  isExporting: !!options.isExporting,
@@ -806,20 +818,30 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
806
818
  }
807
819
  // Append support for redirecting unhandled requests to the index.html page on web.
808
820
  if (this.isTargetingWeb()) {
809
- if (!useServerRendering || isReactServerComponentsEnabled) {
821
+ if (!useServerRendering) {
810
822
  // This MUST run last since it's the fallback.
811
823
  middleware.use(new _historyFallbackMiddleware.HistoryFallbackMiddleware(manifestMiddleware.getHandler().internal).getHandler());
812
824
  } else {
813
- var ref8;
825
+ var ref11;
814
826
  middleware.use((0, _createServerRouteMiddleware.createRouteHandlerMiddleware)(this.projectRoot, {
815
827
  appDir,
816
828
  routerRoot,
817
829
  config,
818
- ...(ref8 = config.exp.extra) == null ? void 0 : ref8.router,
830
+ ...(ref11 = config.exp.extra) == null ? void 0 : ref11.router,
819
831
  bundleApiRoute: (functionFilePath)=>this.ssrImportApiRoute(functionFilePath, {
820
832
  platform: "web"
821
833
  }),
822
- getStaticPageAsync: (pathname)=>{
834
+ getStaticPageAsync: async (pathname)=>{
835
+ // TODO: Add server rendering when RSC is enabled.
836
+ if (isReactServerComponentsEnabled) {
837
+ // NOTE: This is a temporary hack to return the SPA/template index.html in development when RSC is enabled.
838
+ // While this technically works, it doesn't provide the correct experience of server rendering the React code to HTML first.
839
+ const html = await manifestMiddleware.getSingleHtmlTemplateAsync();
840
+ return {
841
+ content: html
842
+ };
843
+ }
844
+ // Non-RSC apps will bundle the static HTML for a given pathname and respond with it.
823
845
  return this.getStaticPageAsync(pathname);
824
846
  }
825
847
  }));
@@ -890,8 +912,21 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
890
912
  // NOTE: We throw away the updates and instead simply send a trigger to the client to re-fetch the server route.
891
913
  if (!isInitialUpdate && hasUpdate) {
892
914
  // Clear all SSR modules before sending the reload event. This ensures that the next event will rebuild the in-memory state from scratch.
893
- // if (typeof globalThis.__c === 'function') globalThis.__c();
894
- onReload();
915
+ // @ts-expect-error
916
+ if (typeof globalThis.__c === "function") globalThis.__c();
917
+ const allModuleIds = new Set([
918
+ ...added,
919
+ ...modified
920
+ ].map((m)=>m.module[0]).concat(deleted));
921
+ const platforms = unique(Array.from(allModuleIds).map((moduleId)=>{
922
+ var ref;
923
+ if (typeof moduleId !== "string") {
924
+ return null;
925
+ }
926
+ // Extract platforms from the module IDs.
927
+ return ((ref = moduleId.match(/[?&]platform=([\w]+)/)) == null ? void 0 : ref[1]) ?? null;
928
+ }).filter(Boolean));
929
+ onReload(platforms);
895
930
  }
896
931
  }
897
932
  break;
@@ -1063,14 +1098,23 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
1063
1098
  }
1064
1099
  // Metro HMR
1065
1100
  setupHmr(url) {
1066
- const onReload = ()=>{
1067
- var _obj, ref;
1101
+ const onReload = (platforms = [])=>{
1068
1102
  // Send reload command to client from Fast Refresh code.
1069
- debug("[SSR]: Reload requested.");
1070
- (ref = (_obj = this).onReloadRscEvent) == null ? void 0 : ref.call(_obj);
1071
- this.broadcastMessage("sendDevCommand", {
1072
- name: "rsc-reload"
1073
- });
1103
+ if (!platforms.length) {
1104
+ // TODO: When is this called?
1105
+ this.broadcastMessage("sendDevCommand", {
1106
+ name: "rsc-reload"
1107
+ });
1108
+ } else {
1109
+ for (const platform of platforms){
1110
+ var _obj, ref;
1111
+ (ref = (_obj = this).onReloadRscEvent) == null ? void 0 : ref.call(_obj, platform);
1112
+ this.broadcastMessage("sendDevCommand", {
1113
+ name: "rsc-reload",
1114
+ platform
1115
+ });
1116
+ }
1117
+ }
1074
1118
  };
1075
1119
  this.registerSsrHmrAsync(url.toString(), onReload);
1076
1120
  }
@@ -1238,6 +1282,9 @@ class MetroBundlerDevServer extends _bundlerDevServer.BundlerDevServer {
1238
1282
  map: bundleMap
1239
1283
  };
1240
1284
  } catch (error1) {
1285
+ // Mark the error so we know how to format and return it later.
1286
+ // @ts-expect-error
1287
+ error1[_metroErrorInterface.IS_METRO_BUNDLE_ERROR_SYMBOL] = true;
1241
1288
  this.metro._reporter.update({
1242
1289
  buildID: getBuildID(buildNumber),
1243
1290
  type: "bundle_build_failed"
@@ -1283,5 +1330,8 @@ async function sourceMapStringAsync(modules, options) {
1283
1330
  excludeSource: options.excludeSource
1284
1331
  });
1285
1332
  }
1333
+ function unique(array) {
1334
+ return Array.from(new Set(array));
1335
+ }
1286
1336
 
1287
1337
  //# sourceMappingURL=MetroBundlerDevServer.js.map