mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
* fix(android): support source-based APK builds Co-authored-by: Anton Lazarev <22821309+antonok-edm@users.noreply.github.com> * fix(android): address fdroid review feedback Co-authored-by: Anton Lazarev <22821309+antonok-edm@users.noreply.github.com> * fix(android): complete the F-Droid build profile * fix(app): isolate the F-Droid runtime flag --------- Co-authored-by: Anton Lazarev <22821309+antonok-edm@users.noreply.github.com>
124 lines
4.3 KiB
JavaScript
124 lines
4.3 KiB
JavaScript
const { getDefaultConfig } = require("expo/metro-config");
|
|
const { resolve } = require("metro-resolver");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
|
|
const projectRoot = __dirname;
|
|
const appNodeModulesRoot = path.resolve(projectRoot, "node_modules");
|
|
const appSrcRoot = path.resolve(projectRoot, "src");
|
|
const relaySrcRoot = path.resolve(projectRoot, "../relay/src");
|
|
const isFdroidBuild = process.env.PASEO_FDROID_BUILD === "1";
|
|
const fdroidModuleOverrides = {
|
|
"expo-camera": path.resolve(appSrcRoot, "fdroid/expo-camera.tsx"),
|
|
"expo-notifications": path.resolve(appSrcRoot, "fdroid/expo-notifications.ts"),
|
|
};
|
|
const customWebPlatform = (process.env.PASEO_WEB_PLATFORM ?? "")
|
|
.trim()
|
|
.replace(/^\./, "")
|
|
.toLowerCase();
|
|
|
|
const config = getDefaultConfig(projectRoot);
|
|
const defaultResolveRequest = config.resolver.resolveRequest ?? resolve;
|
|
|
|
// Keep app exports deterministic across dev machines and CI. Metro's Watchman
|
|
// crawler behavior depends on the host Watchman build/capabilities, while the
|
|
// node crawler is the path used when Watchman is absent.
|
|
config.resolver.useWatchman = false;
|
|
|
|
const escapedAppSrcRoot = appSrcRoot
|
|
.split(path.sep)
|
|
.map((segment) => segment.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&"))
|
|
.join("[\\\\/]");
|
|
const pathSeparatorPattern = "[\\\\/]";
|
|
|
|
config.resolver.extraNodeModules = {
|
|
...config.resolver.extraNodeModules,
|
|
react: path.join(appNodeModulesRoot, "react"),
|
|
"react-dom": path.join(appNodeModulesRoot, "react-dom"),
|
|
"react/jsx-runtime": path.join(appNodeModulesRoot, "react/jsx-runtime"),
|
|
"react/jsx-dev-runtime": path.join(appNodeModulesRoot, "react/jsx-dev-runtime"),
|
|
};
|
|
config.resolver.blockList = new RegExp(
|
|
`(^${escapedAppSrcRoot}${pathSeparatorPattern}.*\\.(test|spec)\\.(ts|tsx)$|${pathSeparatorPattern}__tests__${pathSeparatorPattern}.*)$`,
|
|
);
|
|
|
|
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 "<custom-platform>.<ext>" 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) => {
|
|
if (isFdroidBuild && platform === "android" && fdroidModuleOverrides[moduleName]) {
|
|
return resolveWithCustomWebOverlay(context, fdroidModuleOverrides[moduleName], platform);
|
|
}
|
|
|
|
const origin = context.originModulePath;
|
|
if (origin && origin.startsWith(relaySrcRoot) && moduleName.endsWith(".js")) {
|
|
const tsModuleName = moduleName.replace(/\.js$/, ".ts");
|
|
const candidatePath = path.resolve(path.dirname(origin), tsModuleName);
|
|
if (fs.existsSync(candidatePath)) {
|
|
return resolveWithCustomWebOverlay(context, tsModuleName, platform);
|
|
}
|
|
}
|
|
|
|
return resolveWithCustomWebOverlay(context, moduleName, platform);
|
|
};
|
|
|
|
if (process.env.PASEO_SERVE_SIM_PREVIEW === "1") {
|
|
const { simMiddleware } = require("serve-sim/middleware");
|
|
const originalEnhanceMiddleware = config.server?.enhanceMiddleware;
|
|
config.server = config.server ?? {};
|
|
config.server.enhanceMiddleware = (metroMiddleware, server) => {
|
|
const middleware = originalEnhanceMiddleware
|
|
? originalEnhanceMiddleware(metroMiddleware, server)
|
|
: metroMiddleware;
|
|
const serveSimulator = simMiddleware({
|
|
basePath: "/.sim",
|
|
device: process.env.PASEO_SERVE_SIM_DEVICE_UDID,
|
|
});
|
|
return (req, res, next) => {
|
|
serveSimulator(req, res, (error) => {
|
|
if (error) {
|
|
if (next) {
|
|
next(error);
|
|
return;
|
|
}
|
|
throw error;
|
|
}
|
|
middleware(req, res, next);
|
|
});
|
|
};
|
|
};
|
|
}
|
|
|
|
module.exports = config;
|