expo-desktop 0.1.32 → 0.1.34
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/build/common/npm.js
CHANGED
|
@@ -51,6 +51,7 @@ export async function newExpoDesktopProject(args) {
|
|
|
51
51
|
},
|
|
52
52
|
{ value: "bun", label: `Bun${platform === "darwin" ? " (recommended)" : ""}` },
|
|
53
53
|
{ value: "pnpm", label: `pnpm${platform === "win32" ? " (recommended)" : ""}` },
|
|
54
|
+
{ value: "yarn", label: "yarn" },
|
|
54
55
|
],
|
|
55
56
|
initialValue: platform === "darwin" ? "bun" : platform === "win32" ? "pnpm" : "npm",
|
|
56
57
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { log, tasks } from "@clack/prompts";
|
|
2
2
|
import { type } from "arktype";
|
|
3
|
+
import { glob } from "glob";
|
|
3
4
|
import { cyan, green, yellow } from "kleur/colors";
|
|
4
5
|
import fs from "node:fs/promises";
|
|
5
6
|
import path from "node:path";
|
|
@@ -66,11 +67,13 @@ export async function createExpoDesktopApp({ localDev, name, packageManager, tem
|
|
|
66
67
|
if (localDev) {
|
|
67
68
|
await addApplyConfigPluginsScript({ projectPath });
|
|
68
69
|
}
|
|
70
|
+
const bundleEntryFileCandidates = await getBundleEntryFileCandidates({ projectPath });
|
|
69
71
|
await applyConfigPlugins({
|
|
70
72
|
projectRoot: projectPath,
|
|
71
73
|
displayName: name.displayName,
|
|
72
74
|
bundleIdentifier: name.rdns.replaceAll("_", "-"),
|
|
73
75
|
platforms: ["macos", "windows"],
|
|
76
|
+
bundleEntryFileCandidates,
|
|
74
77
|
});
|
|
75
78
|
console.log(`${green("◆")} Applied config plugins.\n`);
|
|
76
79
|
title("Improving the macOS app's gitignore file…", { spacing: 1 });
|
|
@@ -100,6 +103,30 @@ export async function createExpoDesktopApp({ localDev, name, packageManager, tem
|
|
|
100
103
|
await improveMetroConfig({ projectPath });
|
|
101
104
|
title("Adding Expo support to the Babel config…", { spacing: 1 });
|
|
102
105
|
await writeBabelConfig({ projectPath });
|
|
106
|
+
logProjectReady({ cdPath: name.filesafeName, packageManager });
|
|
107
|
+
}
|
|
108
|
+
async function getBundleEntryFileCandidates({ projectPath }) {
|
|
109
|
+
try {
|
|
110
|
+
// Seems to order candidates as:
|
|
111
|
+
// [
|
|
112
|
+
// "index.windows.tsx",
|
|
113
|
+
// "index.windows.ts",
|
|
114
|
+
// "index.windows.jsx",
|
|
115
|
+
// "index.windows.js",
|
|
116
|
+
// "index.tsx",
|
|
117
|
+
// "index.ts",
|
|
118
|
+
// "index.jsx",
|
|
119
|
+
// "index.js",
|
|
120
|
+
// ]
|
|
121
|
+
const candidates = await glob("index?(.windows|.macos|.ios|.android|.native).{ts,tsx,js,jsx}", {
|
|
122
|
+
cwd: projectPath,
|
|
123
|
+
});
|
|
124
|
+
return candidates;
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.warn("Unable to detect an index?(.windows).{ts,tsx,js,jsx} file in the root of the project, so will fall back to a <BundleEntryFile> value to 'index.ts'.", error);
|
|
128
|
+
return ["index.ts"];
|
|
129
|
+
}
|
|
103
130
|
}
|
|
104
131
|
async function createExpoApp({ localDev, name, packageManager, versions, }) {
|
|
105
132
|
// `create-expo-app` aggravatingly reconfigures your workspace to use
|
|
@@ -118,10 +145,17 @@ async function createExpoApp({ localDev, name, packageManager, versions, }) {
|
|
|
118
145
|
});
|
|
119
146
|
await gen.next();
|
|
120
147
|
// `npm create` drops flags meant for create-expo-app unless you add `--`; use
|
|
121
|
-
// `npx --yes` instead to forward args correctly
|
|
148
|
+
// `npx --yes` instead to forward args correctly. Pass `--yes` to
|
|
149
|
+
// create-expo-app for non-interactive template selection; set `CI=true` in the
|
|
150
|
+
// child env so git-init inside an existing repo is skipped too.
|
|
122
151
|
const command = packageManager === "npm" ? "npx" : packageManager;
|
|
152
|
+
let packageManagerArgs = ["create", "expo-app@latest"];
|
|
153
|
+
if (packageManager === "npm")
|
|
154
|
+
packageManagerArgs = ["--yes", "create-expo-app@latest"];
|
|
155
|
+
if (packageManager === "yarn")
|
|
156
|
+
packageManagerArgs = ["create", "expo-app"];
|
|
123
157
|
const args = [
|
|
124
|
-
...
|
|
158
|
+
...packageManagerArgs,
|
|
125
159
|
name.filesafeName,
|
|
126
160
|
"--yes",
|
|
127
161
|
"--template",
|
|
@@ -138,8 +172,15 @@ async function createExpoApp({ localDev, name, packageManager, versions, }) {
|
|
|
138
172
|
args,
|
|
139
173
|
options: {
|
|
140
174
|
stdio: "inherit",
|
|
141
|
-
|
|
142
|
-
|
|
175
|
+
env: {
|
|
176
|
+
// Suppresses npx/npm exec "Ok to proceed?" and similar yes/no prompts.
|
|
177
|
+
npm_config_yes: "true",
|
|
178
|
+
// create-expo-app's `--yes` skips template/SDK prompts but not the
|
|
179
|
+
// "Skip initializing a new git repository?" confirm when cwd is
|
|
180
|
+
// inside an existing repo; that path only auto-skips when CI is set.
|
|
181
|
+
// https://github.com/expo/expo/blob/main/packages/create-expo/src/utils/git.ts
|
|
182
|
+
CI: "true",
|
|
183
|
+
},
|
|
143
184
|
},
|
|
144
185
|
debugLogDir: projectPath,
|
|
145
186
|
}),
|
|
@@ -287,13 +328,40 @@ async function updatePackageJson({ localDev, name, projectPath, task, versions,
|
|
|
287
328
|
if (!packageJson.overrides) {
|
|
288
329
|
packageJson.overrides = {};
|
|
289
330
|
}
|
|
290
|
-
// react
|
|
291
|
-
//
|
|
292
|
-
|
|
293
|
-
|
|
331
|
+
// The "react" version in expo-template-blank-typescript for SDK 54 is
|
|
332
|
+
// 19.1.0, but it needs to be 19.1.4 to satisfy react-native-macos and
|
|
333
|
+
// react-native-windows. We find that the React Native HelloWorld template
|
|
334
|
+
// is more reliable as a source of truth for the best "react" and
|
|
335
|
+
// "react-native" versions to satisfy them, but it's still a best of a bad
|
|
336
|
+
// job.
|
|
337
|
+
let facebookDeps;
|
|
338
|
+
try {
|
|
339
|
+
const packageJson = (await getReactNativePackageJson(versions.minor));
|
|
340
|
+
facebookDeps = {
|
|
341
|
+
react: packageJson.dependencies.react,
|
|
342
|
+
"react-native": packageJson.dependencies["react-native"],
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
// It's totally possible to get rate-limited by the GitHub API, so we'll
|
|
347
|
+
// avoid failing the entire command just for a bad fetch here.
|
|
348
|
+
console.warn(`Unable to get the ideal dependency versions for "react" and "react-native" from the official React Native HelloWorld template, so will use the ones from the Expo template as-is.`, error);
|
|
349
|
+
}
|
|
350
|
+
if (facebookDeps) {
|
|
351
|
+
packageJson.dependencies.react = facebookDeps.react;
|
|
352
|
+
packageJson.overrides.react = facebookDeps.react;
|
|
353
|
+
packageJson.dependencies["react-native"] = facebookDeps["react-native"];
|
|
354
|
+
packageJson.overrides["react-native"] = facebookDeps["react-native"];
|
|
294
355
|
}
|
|
295
|
-
|
|
296
|
-
|
|
356
|
+
else {
|
|
357
|
+
// react-native-macos and react-native-windows may declare conflicting
|
|
358
|
+
// peer dependency ranges to what the Expo template provides.
|
|
359
|
+
if (packageJson.dependencies.react) {
|
|
360
|
+
packageJson.overrides.react = packageJson.dependencies.react;
|
|
361
|
+
}
|
|
362
|
+
if (packageJson.dependencies["react-native"]) {
|
|
363
|
+
packageJson.overrides["react-native"] = packageJson.dependencies["react-native"];
|
|
364
|
+
}
|
|
297
365
|
}
|
|
298
366
|
}
|
|
299
367
|
try {
|
|
@@ -305,6 +373,10 @@ async function updatePackageJson({ localDev, name, projectPath, task, versions,
|
|
|
305
373
|
console.log(`${green("◆")} Altered package.json.\n`);
|
|
306
374
|
return { name: nameBefore };
|
|
307
375
|
}
|
|
376
|
+
async function getReactNativePackageJson(minor) {
|
|
377
|
+
const response = await fetch(`https://raw.githubusercontent.com/facebook/react-native/refs/heads/0.${minor}-stable/private/helloworld/package.json`);
|
|
378
|
+
return await response.json();
|
|
379
|
+
}
|
|
308
380
|
async function npmInstall({ asNewWorkspace, cwd, packageManager, }) {
|
|
309
381
|
const command = packageManager;
|
|
310
382
|
const args = ["install"];
|
|
@@ -558,6 +630,7 @@ module.exports = function (api) {
|
|
|
558
630
|
*/
|
|
559
631
|
async function addApplyConfigPluginsScript({ projectPath }) {
|
|
560
632
|
await fs.writeFile(path.resolve(projectPath, "apply-config-plugins.mjs"), `
|
|
633
|
+
import { globSync } from "node:fs";
|
|
561
634
|
import { createRequire } from "node:module";
|
|
562
635
|
|
|
563
636
|
const require = createRequire(import.meta.url);
|
|
@@ -572,8 +645,24 @@ const info = {
|
|
|
572
645
|
bundleIdentifier: "com.example.my-app-123",
|
|
573
646
|
// @ts-expect-error Normally only accepts ios and android
|
|
574
647
|
platforms: ["macos", "windows"],
|
|
648
|
+
bundleEntryFileCandidates: getBundleEntryFileCandidates({ projectPath: projectRoot }),
|
|
575
649
|
};
|
|
576
650
|
|
|
651
|
+
function getBundleEntryFileCandidates({ projectPath }) {
|
|
652
|
+
try {
|
|
653
|
+
const candidates = globSync("index{.windows,.macos,.ios,.android,.native,}.{ts,tsx,js,jsx}", {
|
|
654
|
+
cwd: projectPath,
|
|
655
|
+
});
|
|
656
|
+
return candidates;
|
|
657
|
+
} catch (error) {
|
|
658
|
+
console.warn(
|
|
659
|
+
"Unable to detect an index?(.windows).{ts,tsx,js,jsx} file in the root of the project, so will fall back to a <BundleEntryFile> value to 'index.ts'.",
|
|
660
|
+
error,
|
|
661
|
+
);
|
|
662
|
+
return ["index.ts"];
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
577
666
|
const withInternal = (config, internals) => {
|
|
578
667
|
config._internal = {
|
|
579
668
|
isDebug: false,
|
|
@@ -644,3 +733,36 @@ async function applyConfigPlugins(options) {
|
|
|
644
733
|
await applyConfigPlugins(info);
|
|
645
734
|
`.trim() + "\n", "utf-8");
|
|
646
735
|
}
|
|
736
|
+
function logProjectReady({ cdPath, packageManager, }) {
|
|
737
|
+
const lines = [
|
|
738
|
+
"✅ Your project is ready!",
|
|
739
|
+
"",
|
|
740
|
+
"To run your project, first navigate to the directory and start up the packager:",
|
|
741
|
+
"",
|
|
742
|
+
`- cd ${cdPath}`,
|
|
743
|
+
`- ${formatRunCommand(packageManager, "start")}`,
|
|
744
|
+
"",
|
|
745
|
+
"… and then run the target platform of your choice:",
|
|
746
|
+
"",
|
|
747
|
+
`- ${formatRunCommand(packageManager, "android")}`,
|
|
748
|
+
`- ${formatRunCommand(packageManager, "ios")}`,
|
|
749
|
+
`- ${formatRunCommand(packageManager, "web")}`,
|
|
750
|
+
`- ${formatRunCommand(packageManager, "macos")}`,
|
|
751
|
+
`- ${formatRunCommand(packageManager, "windows")}`,
|
|
752
|
+
"",
|
|
753
|
+
];
|
|
754
|
+
log.success(lines.join("\n"), { withGuide: false });
|
|
755
|
+
}
|
|
756
|
+
export function formatRunCommand(packageManager, cmd) {
|
|
757
|
+
switch (packageManager) {
|
|
758
|
+
case "pnpm":
|
|
759
|
+
return `pnpm run ${cmd}`;
|
|
760
|
+
case "yarn":
|
|
761
|
+
return `yarn ${cmd}`;
|
|
762
|
+
case "bun":
|
|
763
|
+
return `bun run ${cmd}`;
|
|
764
|
+
case "npm":
|
|
765
|
+
default:
|
|
766
|
+
return `npm run ${cmd}`;
|
|
767
|
+
}
|
|
768
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "expo-desktop",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
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.
|
|
41
|
-
"expo-desktop-prebuild-config": "^1.0.
|
|
40
|
+
"expo-desktop-config-plugins": "^1.1.31",
|
|
41
|
+
"expo-desktop-prebuild-config": "^1.0.17",
|
|
42
42
|
"glob": "^10.5.0",
|
|
43
43
|
"kleur": "^4.1.5",
|
|
44
44
|
"mustache": "^4.2.0",
|