Description
Description
Hi, I'm currently developing an application with repack and expo (with CNG and router), in order to make it work I had to revert some stuff that expo does, which basically is:
- Replacing expo cli with rn cli (to support development)
- Removing CLI_PATH and BUNDLE_COMMAND from ios and android targets (to support release)
- Changing jsMainBundle from
.expo/.virtual-metro-entry
toindex
(in AppDelegate.mm and MainApplication.kt) - Added some environment variables via define plugin:
new DefinePlugin({
"__DEV__": JSON.stringify(mode === "development"),
"process.env.EXPO_BASE_URL": JSON.stringify(""),
"process.env.EXPO_OS": JSON.stringify(platform),
"process.env.EXPO_PROJECT_ROOT": JSON.stringify(resolve(".")),
"process.env.EXPO_ROUTER_ABS_APP_ROOT": JSON.stringify(resolve("./src/screens")),
"process.env.EXPO_ROUTER_APP_ROOT": JSON.stringify("~/screens"),
"process.env.EXPO_ROUTER_IMPORT_MODE": JSON.stringify("sync"),
"process.env.NODE_ENV": JSON.stringify(mode),
})
Everything works (both debug and release builds). But recently expo added an override in ios that enforce the jsMainBundle to be .expo/.virtual-metro-entry
, so in order to fix that I've patched node_modules/expo-modules-core/ios/AppDelegates/ExpoAppInstance
:
diff --git a/ios/AppDelegates/ExpoAppInstance.swift b/ios/AppDelegates/ExpoAppInstance.swift
index 8dae3f001009f98ff100c162131d59a915a68e73..b1fe5b8ed69e6e4090c5d961b6990761d873ee0d 100644
--- a/ios/AppDelegates/ExpoAppInstance.swift
+++ b/ios/AppDelegates/ExpoAppInstance.swift
@@ -14,7 +14,7 @@ open class ExpoAppInstance: RCTAppDelegate {
open override func bundleURL() -> URL? {
#if DEBUG
- return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
This solution works but it kinda sucks (personally I don't like to patch packages).
Suggested solution
I think that repack could support some sort of redirect in devServer, this will dramatically reduce my setup to make it work. A simple redirect from .expo/.virtual-metro-entry
to index
with the same query params should fix it. What you think?
Additional context
My expo configuration plugin just for reference (if anyone came across this issue):
import type { ExpoConfig } from "expo/config";
import { withAppBuildGradle, withAppDelegate, withMainApplication, withXcodeProject } from "expo/config-plugins";
export default function plugin(expo: ExpoConfig) {
let res = expo;
// iOS
res = withXcodeProject(res, async (configuration) => {
const xcodeProject = configuration.modResults;
const bundleReactNativeCodeAndImagesBuildPhase = xcodeProject.buildPhaseObject(
"PBXShellScriptBuildPhase",
"Bundle React Native code and images",
);
if (!bundleReactNativeCodeAndImagesBuildPhase)
return configuration;
const script = JSON.parse(bundleReactNativeCodeAndImagesBuildPhase.shellScript);
const patched = script
.replace(/if \[\[ -z "\$CLI_PATH" \]\]; then[\s\S]*?fi\n?/g, `export CLI_PATH="$("$NODE_BINARY" --print "require('path').dirname(require.resolve('@react-native-community/cli/package.json')) + '/build/bin.js'")"`)
.replace(/if \[\[ -z "\$BUNDLE_COMMAND" \]\]; then[\s\S]*?fi\n?/g, "");
bundleReactNativeCodeAndImagesBuildPhase.shellScript = JSON.stringify(patched);
return configuration;
});
res = withAppDelegate(res, async (configuration) => {
const appDelegate = configuration.modResults.contents;
configuration.modResults.contents = appDelegate.replace(".expo/.virtual-metro-entry", "index");
return configuration;
});
// Android
res = withMainApplication(res, async (configuration) => {
const mainApplication = configuration.modResults.contents;
configuration.modResults.contents = mainApplication.replace(".expo/.virtual-metro-entry", "index");
return configuration;
});
res = withAppBuildGradle(res, async (config) => {
const buildGradle = config.modResults.contents;
const patched = buildGradle.replace(/cliFile.*/, "").replace(/bundleCommand.*/, "bundleCommand = \"bundle\"");
config.modResults.contents = patched;
return config;
});
return res;
}