expo-desktop 0.1.19 → 0.1.20

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.
@@ -87,11 +87,20 @@ export async function createExpoDesktopApp({ localDev, name, packageManager, tem
87
87
  title("Installing Cocoapods for the macOS app…", { spacing: 1 });
88
88
  await podInstall({ projectPath, type: "macos" });
89
89
  }
90
+ // react-native config seems to return `windows: null` on non-Windows
91
+ // platforms (while returning a populated object for Windows). If you force it
92
+ // to non-null for development on macOS, macOS runs the autolinking command
93
+ // successfully but writes out erroneous output, so
94
+ // there's no point.
95
+ if (platform === "win32") {
96
+ title("Autolinking the Windows app…", { spacing: 1 });
97
+ await autolinkWindows({ projectPath });
98
+ }
90
99
  title("Adding Expo support to the Metro config…", { spacing: 1 });
91
100
  await improveMetroConfig({ projectPath });
101
+ await addWindowsExpoPolyfill({ projectPath });
92
102
  title("Adding Expo support to the Babel config…", { spacing: 1 });
93
103
  await writeBabelConfig({ projectPath });
94
- // TODO: Set up Windows app.cpp entrypoint
95
104
  }
96
105
  async function createExpoApp({ localDev, name, packageManager, versions, }) {
97
106
  // `create-expo-app` aggravatingly reconfigures your workspace to use
@@ -249,19 +258,21 @@ async function updatePackageJson({ localDev, name, projectPath, task, versions,
249
258
  }
250
259
  packageJson.scripts.macos = "rnc-cli run-macos";
251
260
  packageJson.scripts.windows = "rnc-cli run-windows";
261
+ packageJson.scripts["autolink-windows"] = "react-native autolink-windows";
252
262
  }
253
263
  else {
254
264
  if (!packageJson.dependencies) {
255
265
  packageJson.dependencies = {};
256
266
  }
257
- // expo-desktop-prebuild-config itself depends on
258
- // expo-desktop-config-plugins.
259
- if (localDev) {
260
- packageJson.dependencies["expo-desktop-prebuild-config"] =
261
- "file:../../expo-desktop-prebuild-config";
262
- }
263
- else {
264
- packageJson.dependencies["expo-desktop-prebuild-config"] = "^1.0.0";
267
+ const monorepoDeps = {
268
+ // expo-desktop-prebuild-config itself depends on
269
+ // expo-desktop-config-plugins.
270
+ ["expo-desktop-prebuild-config"]: "^1.0.0",
271
+ ["expo-desktop-modules-core"]: `^${versions.expoMajor}.0.0`,
272
+ ["expo-desktop-stubs"]: `^${versions.expoMajor}.0.0`,
273
+ };
274
+ for (const [key, value] of Object.entries(monorepoDeps)) {
275
+ packageJson.dependencies[key] = localDev ? `file:../../${key}` : value;
265
276
  }
266
277
  packageJson.dependencies["react-native-macos"] = versions.macos;
267
278
  packageJson.dependencies["react-native-windows"] = versions.windows;
@@ -428,6 +439,27 @@ async function podInstall({ projectPath, type }) {
428
439
  }
429
440
  console.log(`\n${green("◆")} Installed Cocoapods for the ${type === "ios" ? "iOS" : "macOS"} app.\n`);
430
441
  }
442
+ async function autolinkWindows({ projectPath }) {
443
+ const command = "node";
444
+ const args = ["--run", "autolink-windows"];
445
+ const printedCommand = `${command} ${args.join(" ")}`;
446
+ console.log(`${cyan("◆")} Running: ${yellow(printedCommand)}\n`);
447
+ try {
448
+ await tasks([
449
+ promisifiedSpawnTask({
450
+ title: "react-native autolink-windows",
451
+ command,
452
+ args,
453
+ options: { cwd: projectPath, stdio: "inherit" },
454
+ }),
455
+ ]);
456
+ }
457
+ catch (error) {
458
+ log.error(`Error running ${yellow(printedCommand)}${error instanceof Error ? `: ${error.message}` : "."}`);
459
+ process.exit(1);
460
+ }
461
+ console.log(`\n${green("◆")} Autolinked the Windows app.\n`);
462
+ }
431
463
  async function improveMetroConfig({ projectPath }) {
432
464
  const metroConfigPath = path.resolve(projectPath, "metro.config.js");
433
465
  console.log(`${cyan("◆")} Overwriting metro.config.js…\n`);
@@ -437,6 +469,17 @@ const { getDefaultConfig } = require("@expo/metro-config");
437
469
  const { makeMetroConfig } = require("@rnx-kit/metro-config");
438
470
 
439
471
  const config = makeMetroConfig(getDefaultConfig(__dirname));
472
+
473
+ const getPolyfills = config.serializer.getPolyfills;
474
+ const windowsExpoPolyfill = require.resolve("./expo-polyfill.windows.js");
475
+ config.serializer.getPolyfills = (platform) => {
476
+ const polyfills = getPolyfills(platform);
477
+ if (platform === "windows") {
478
+ polyfills.push(windowsExpoPolyfill);
479
+ }
480
+ return polyfills;
481
+ };
482
+
440
483
  module.exports = config;
441
484
  `.trim() + "\n", "utf-8");
442
485
  }
@@ -446,6 +489,69 @@ module.exports = config;
446
489
  }
447
490
  console.log(`\n${green("◆")} Overwrote metro.config.js.\n`);
448
491
  }
492
+ /**
493
+ */
494
+ async function addWindowsExpoPolyfill({ projectPath }) {
495
+ await fs.writeFile(path.resolve(projectPath, "expo-polyfill.windows.js"), `
496
+ try {
497
+ // Until we can configure TurboModules for eager initialisation (which is
498
+ // waiting on https://github.com/microsoft/react-native-windows/pull/16093), we
499
+ // need to trigger the lazy-init of our TurboModule by accessing it for the
500
+ // first time, which causes the TurboModuleManager to call its REACT_INIT
501
+ // method.
502
+ //
503
+ // We can't do any imports inside getPolyfills(), but can use the global proxy:
504
+ globalThis.nativeModuleProxy.ExpoMainRuntimeInstaller;
505
+
506
+ // TODO: Implement Expo's NativeModulesProxy and make all of this
507
+ // lazy-initialised (and actually populate \`exportedMethods\`, etc.).
508
+
509
+ // Below are temporary stubs to suppress these warnings:
510
+ // WARN The "EXNativeModulesProxy" native module is not exported through NativeModules; verify that expo-modules-core's native code is linked properly
511
+ // WARN No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?
512
+ // WARN No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?
513
+
514
+ // Funnily enough, although expo-modules-core prefers to access
515
+ // global.expo?.modules?.NativeModulesProxy over the deprecated
516
+ // NativeModules?.NativeUnimoduleProxy, we still need the latter to exist in
517
+ // order for it to check the former. And it's only
518
+ globalThis.nativeModuleProxy.NativeUnimoduleProxy;
519
+ const { ExpoAsset } = globalThis.nativeModuleProxy;
520
+
521
+ const ExponentConstants = {};
522
+
523
+ globalThis.expo.modules = {
524
+ ExpoAsset,
525
+ ExponentConstants,
526
+ // - JS: apps/demo/node_modules/expo-modules-core/src/NativeModulesProxy.native.ts
527
+ // - iOS:
528
+ // - NativeUnimoduleProxy: apps/demo/node_modules/expo-modules-core/ios/Legacy/NativeModulesProxy/NativeModulesProxyModule.swift
529
+ // - NativeModulesProxy: apps/demo/node_modules/expo-modules-core/ios/Legacy/NativeModulesProxy/EXNativeModulesProxy.mm
530
+ // - Android:
531
+ // - NativeUnimoduleProxy: apps/demo/node_modules/expo-modules-core/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java
532
+ // - NativeModulesProxy: apps/demo/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/defaultmodules/NativeModulesProxyModule.kt
533
+ NativeModulesProxy: {
534
+ exportedMethods: {
535
+ ExpoAsset: [],
536
+ ExponentConstants: [],
537
+ },
538
+ modulesConstants: {
539
+ ExpoAsset: [],
540
+ ExponentConstants: [],
541
+ },
542
+ },
543
+ };
544
+
545
+ // Now expo-modules-core can populate its fileprivate
546
+ // \`const NativeModulesProxy: Record<string, ProxyNativeModule = {}\` from our
547
+ // global.expo?.modules?.NativeModulesProxy. This avoids the warning about
548
+ // EXNativeModulesProxy being missing.
549
+ } catch (error) {
550
+ console.error("Polyfill failed", error);
551
+ throw error;
552
+ }
553
+ `.trim() + "\n", "utf-8");
554
+ }
449
555
  async function updatePodfile({ projectPath }) {
450
556
  const appJsonPath = path.resolve(projectPath, "macos/Podfile");
451
557
  let contents;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-desktop",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "Best-effort desktop support for Expo",
5
5
  "keywords": [
6
6
  "android",
@@ -41,8 +41,8 @@
41
41
  "kleur": "^4.1.5",
42
42
  "mustache": "^4.2.0",
43
43
  "toml": "^4.1.1",
44
- "expo-desktop-config-plugins": "1.1.19",
45
- "expo-desktop-prebuild-config": "1.0.8"
44
+ "expo-desktop-config-plugins": "1.1.20",
45
+ "expo-desktop-prebuild-config": "1.0.9"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@expo/config": "^12.0.13",