From 0d28dae444a6c4f7a1789d0bc1afabee094ec52d Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sun, 22 Feb 2026 11:12:53 +0700 Subject: [PATCH] feat(app): add tauri web overlay module resolution --- packages/app/metro.config.js | 42 ++++++++++++++++++++++++++++++++++-- packages/app/package.json | 2 ++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/packages/app/metro.config.js b/packages/app/metro.config.js index d81793a78..bd77c2a6c 100644 --- a/packages/app/metro.config.js +++ b/packages/app/metro.config.js @@ -7,6 +7,10 @@ const projectRoot = __dirname; const monorepoRoot = path.resolve(projectRoot, "../.."); const serverSrcRoot = path.resolve(projectRoot, "../server/src"); const relaySrcRoot = path.resolve(projectRoot, "../relay/src"); +const customWebPlatform = (process.env.PASEO_WEB_PLATFORM ?? "") + .trim() + .replace(/^\./, "") + .toLowerCase(); const config = getDefaultConfig(projectRoot); const defaultResolveRequest = config.resolver.resolveRequest ?? resolve; @@ -25,6 +29,40 @@ config.resolver.nodeModulesPaths = Array.from( ]) ); +function isLocalModuleImport(moduleName) { + return ( + moduleName.startsWith("./") || + moduleName.startsWith("../") || + moduleName.startsWith("@/") || + path.isAbsolute(moduleName) + ); +} + +function resolveWithCustomWebOverlay(context, moduleName, platform) { + const shouldResolveCustomWebVariant = + platform === "web" && + customWebPlatform.length > 0 && + customWebPlatform !== "web" && + isLocalModuleImport(moduleName); + + if (shouldResolveCustomWebVariant) { + const overlayContext = { + ...context, + // Resolve only "." variants in overlay mode. + sourceExts: context.sourceExts.map((ext) => `${customWebPlatform}.${ext}`), + preferNativePlatform: false, + }; + + try { + return defaultResolveRequest(overlayContext, moduleName, null); + } catch { + // Ignore overlay misses and continue with normal web resolution. + } + } + + return defaultResolveRequest(context, moduleName, platform); +} + config.resolver.resolveRequest = (context, moduleName, platform) => { const origin = context.originModulePath; if ( @@ -35,11 +73,11 @@ config.resolver.resolveRequest = (context, moduleName, platform) => { const tsModuleName = moduleName.replace(/\.js$/, ".ts"); const candidatePath = path.resolve(path.dirname(origin), tsModuleName); if (fs.existsSync(candidatePath)) { - return defaultResolveRequest(context, tsModuleName, platform); + return resolveWithCustomWebOverlay(context, tsModuleName, platform); } } - return defaultResolveRequest(context, moduleName, platform); + return resolveWithCustomWebOverlay(context, moduleName, platform); }; module.exports = config; diff --git a/packages/app/package.json b/packages/app/package.json index 05f6c3166..fae672d20 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -14,6 +14,7 @@ "ios": "expo run:ios", "ios:release": "expo run:ios --configuration Release", "web": "expo start --web", + "web:tauri": "PASEO_WEB_PLATFORM=tauri expo start --web", "lint": "expo lint", "typecheck": "tsc --noEmit", "test": "vitest run", @@ -21,6 +22,7 @@ "test:e2e:ui": "playwright test --ui", "build": "npm run build:web", "build:web": "expo export --platform web", + "build:web:tauri": "PASEO_WEB_PLATFORM=tauri expo export --platform web", "deploy:web": "npm run build:web && wrangler pages deploy dist --project-name paseo-app" }, "dependencies": {