expo-desktop 0.1.29 → 0.1.31

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.
@@ -30,7 +30,7 @@ export async function applyWindowsCppAppTemplateAsync(projectRoot, name) {
30
30
  const replacements = await buildReplacementsRecord(projectRoot, name);
31
31
  await renameCppAppPathsAsync(windowsRoot, name.filesafeName);
32
32
  await renderMustacheUnderWindowsAsync(windowsRoot, replacements);
33
- await finalizeWindowsCppTemplateArtifacts(projectRoot);
33
+ await finalizeWindowsCppTemplateArtifacts(projectRoot, replacements);
34
34
  }
35
35
  async function looksLikeCppAppTemplateAsync(windowsRoot) {
36
36
  try {
@@ -278,29 +278,49 @@ async function renderMustacheUnderWindowsAsync(windowsRoot, view) {
278
278
  if (isProbablyBinaryFile(absoluteFilePath)) {
279
279
  return;
280
280
  }
281
- let content;
282
- try {
283
- content = await fs.readFile(absoluteFilePath, "utf8");
284
- }
285
- catch (error) {
286
- if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
287
- throw error;
288
- }
289
- return;
290
- }
291
- if (!content.includes("{{")) {
292
- return;
293
- }
294
- const useCRLF = content.includes("\r\n");
295
- const adjustedView = adjustReplacementStringsForLineEndings(view, useCRLF);
296
- const rendered = mustache.render(content, adjustedView);
297
- if (rendered !== content) {
298
- await fs.writeFile(absoluteFilePath, rendered, "utf8");
299
- }
281
+ await renderMustacheInFileIfNeeded(absoluteFilePath, view);
300
282
  }));
301
283
  }
302
- async function finalizeWindowsCppTemplateArtifacts(projectRoot) {
284
+ /**
285
+ * Render mustache tags inside `filePath` in place, mirroring the behaviour of
286
+ * react-native-windows' generator-common `resolveContents()`. Skips files that
287
+ * don't exist, files that don't contain any `{{` (no-op fast path), and
288
+ * preserves the file's existing line endings (LF vs CRLF).
289
+ *
290
+ * @see https://github.com/microsoft/react-native-windows/blob/main/packages/%40react-native-windows/cli/src/generator-common/index.ts
291
+ */
292
+ async function renderMustacheInFileIfNeeded(filePath, view) {
293
+ let content;
294
+ try {
295
+ content = await fs.readFile(filePath, "utf8");
296
+ }
297
+ catch (error) {
298
+ if (!(error instanceof Error) || !("code" in error) || error.code !== "ENOENT") {
299
+ throw error;
300
+ }
301
+ return;
302
+ }
303
+ if (!content.includes("{{")) {
304
+ return;
305
+ }
306
+ const useCRLF = content.includes("\r\n");
307
+ const adjustedView = adjustReplacementStringsForLineEndings(view, useCRLF);
308
+ const rendered = mustache.render(content, adjustedView);
309
+ if (rendered !== content) {
310
+ await fs.writeFile(filePath, rendered, "utf8");
311
+ }
312
+ }
313
+ async function finalizeWindowsCppTemplateArtifacts(projectRoot, view) {
303
314
  await renameIfExistsPreferDest(path.join(projectRoot, "NuGet_Config"), path.join(projectRoot, "NuGet.config"));
315
+ // The cpp-app template places NuGet_Config (renamed to NuGet.config above) at
316
+ // the project root rather than under windows/, so renderMustacheUnderWindowsAsync
317
+ // skips it. Render its mustache tags here so that sections like
318
+ // {{#addReactNativePublicAdoFeed}}…{{/addReactNativePublicAdoFeed}} don't leak
319
+ // into the final config and trip up NuGet restore (which manifests downstream
320
+ // as MIDL2025 "syntax error near 'namespace'" in libraries' .idl files,
321
+ // missing `CppWinRTIncludes.h`, and `EntryPointExe '<App>.exe' was not found`
322
+ // packaging errors).
323
+ await renderMustacheInFileIfNeeded(path.join(projectRoot, "NuGet.config"), view);
304
324
  const version = packageJson.version;
305
325
  const banner = `<!-- This project was created with expo-desktop ${version} -->`;
306
326
  const reactNativeWindowsBanner = /<!--\s*This project was created with react-native-windows[^\n\r]*-->/g;
@@ -98,7 +98,6 @@ export async function createExpoDesktopApp({ localDev, name, packageManager, tem
98
98
  }
99
99
  title("Adding Expo support to the Metro config…", { spacing: 1 });
100
100
  await improveMetroConfig({ projectPath });
101
- await addWindowsExpoPolyfill({ projectPath });
102
101
  title("Adding Expo support to the Babel config…", { spacing: 1 });
103
102
  await writeBabelConfig({ projectPath });
104
103
  }
@@ -472,17 +471,6 @@ const { getDefaultConfig } = require("@expo/metro-config");
472
471
  const { makeMetroConfig } = require("@rnx-kit/metro-config");
473
472
 
474
473
  const config = makeMetroConfig(getDefaultConfig(__dirname));
475
-
476
- const getPolyfills = config.serializer.getPolyfills;
477
- const windowsExpoPolyfill = require.resolve("./expo-polyfill.windows.js");
478
- config.serializer.getPolyfills = (...args) => {
479
- const polyfills = getPolyfills(...args);
480
- if (args[0].platform === "windows") {
481
- polyfills.push(windowsExpoPolyfill);
482
- }
483
- return polyfills;
484
- };
485
-
486
474
  module.exports = config;
487
475
  `.trim() + "\n", "utf-8");
488
476
  }
@@ -492,69 +480,6 @@ module.exports = config;
492
480
  }
493
481
  console.log(`\n${green("◆")} Overwrote metro.config.js.\n`);
494
482
  }
495
- /**
496
- */
497
- async function addWindowsExpoPolyfill({ projectPath }) {
498
- await fs.writeFile(path.resolve(projectPath, "expo-polyfill.windows.js"), `
499
- try {
500
- // Until we can configure TurboModules for eager initialisation (which is
501
- // waiting on https://github.com/microsoft/react-native-windows/pull/16093), we
502
- // need to trigger the lazy-init of our TurboModule by accessing it for the
503
- // first time, which causes the TurboModuleManager to call its REACT_INIT
504
- // method.
505
- //
506
- // We can't do any imports inside getPolyfills(), but can use the global proxy:
507
- globalThis.nativeModuleProxy.ExpoMainRuntimeInstaller;
508
-
509
- // TODO: Implement Expo's NativeModulesProxy and make all of this
510
- // lazy-initialised (and actually populate \`exportedMethods\`, etc.).
511
-
512
- // Below are temporary stubs to suppress these warnings:
513
- // WARN The "EXNativeModulesProxy" native module is not exported through NativeModules; verify that expo-modules-core's native code is linked properly
514
- // WARN No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?
515
- // WARN No native ExponentConstants module found, are you sure the expo-constants's module is linked properly?
516
-
517
- // Funnily enough, although expo-modules-core prefers to access
518
- // global.expo?.modules?.NativeModulesProxy over the deprecated
519
- // NativeModules?.NativeUnimoduleProxy, we still need the latter to exist in
520
- // order for it to check the former. And it's only
521
- globalThis.nativeModuleProxy.NativeUnimoduleProxy;
522
- const { ExpoAsset } = globalThis.nativeModuleProxy;
523
-
524
- const ExponentConstants = {};
525
-
526
- globalThis.expo.modules = {
527
- ExpoAsset,
528
- ExponentConstants,
529
- // - JS: apps/demo/node_modules/expo-modules-core/src/NativeModulesProxy.native.ts
530
- // - iOS:
531
- // - NativeUnimoduleProxy: apps/demo/node_modules/expo-modules-core/ios/Legacy/NativeModulesProxy/NativeModulesProxyModule.swift
532
- // - NativeModulesProxy: apps/demo/node_modules/expo-modules-core/ios/Legacy/NativeModulesProxy/EXNativeModulesProxy.mm
533
- // - Android:
534
- // - NativeUnimoduleProxy: apps/demo/node_modules/expo-modules-core/android/src/main/java/expo/modules/adapters/react/NativeModulesProxy.java
535
- // - NativeModulesProxy: apps/demo/node_modules/expo-modules-core/android/src/main/java/expo/modules/kotlin/defaultmodules/NativeModulesProxyModule.kt
536
- NativeModulesProxy: {
537
- exportedMethods: {
538
- ExpoAsset: [],
539
- ExponentConstants: [],
540
- },
541
- modulesConstants: {
542
- ExpoAsset: [],
543
- ExponentConstants: [],
544
- },
545
- },
546
- };
547
-
548
- // Now expo-modules-core can populate its fileprivate
549
- // \`const NativeModulesProxy: Record<string, ProxyNativeModule = {}\` from our
550
- // global.expo?.modules?.NativeModulesProxy. This avoids the warning about
551
- // EXNativeModulesProxy being missing.
552
- } catch (error) {
553
- console.error("Polyfill failed", error);
554
- throw error;
555
- }
556
- `.trim() + "\n", "utf-8");
557
- }
558
483
  async function updatePodfile({ projectPath }) {
559
484
  const appJsonPath = path.resolve(projectPath, "macos/Podfile");
560
485
  let contents;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-desktop",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "description": "Best-effort desktop support for Expo",
5
5
  "keywords": [
6
6
  "android",
@@ -37,8 +37,8 @@
37
37
  "@clack/prompts": "^1.2.0",
38
38
  "arktype": "^2.2.0",
39
39
  "citty": "^0.2.2",
40
- "expo-desktop-config-plugins": "^1.1.27",
41
- "expo-desktop-prebuild-config": "^1.0.13",
40
+ "expo-desktop-config-plugins": "^1.1.28",
41
+ "expo-desktop-prebuild-config": "^1.0.14",
42
42
  "glob": "^10.5.0",
43
43
  "kleur": "^4.1.5",
44
44
  "mustache": "^4.2.0",