Skip to content

Commit

Permalink
Add native module for loading split JS bundles in development
Browse files Browse the repository at this point in the history
Reviewed By: mdvacca, cpojer

Differential Revision: D22001709

fbshipit-source-id: 4e378fd6ae90268e7db9092a71628205b9f7c37d
  • Loading branch information
makovkastar authored and facebook-github-bot committed Jun 17, 2020
1 parent 2e2c881 commit fca3a39
Show file tree
Hide file tree
Showing 15 changed files with 272 additions and 46 deletions.
1 change: 1 addition & 0 deletions ReactAndroid/src/main/java/com/facebook/react/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ rn_android_library(
react_native_target("java/com/facebook/react/module/model:model"),
react_native_target("java/com/facebook/react/modules/appregistry:appregistry"),
react_native_target("java/com/facebook/react/modules/appearance:appearance"),
react_native_target("java/com/facebook/react/modules/bundleloader:bundleloader"),
react_native_target("java/com/facebook/react/modules/debug:debug"),
react_native_target("java/com/facebook/react/modules/fabric:fabric"),
react_native_target("java/com/facebook/react/modules/debug:interfaces"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.facebook.react.module.annotations.ReactModuleList;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.modules.bundleloader.NativeDevSplitBundleLoaderModule;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.modules.core.ExceptionsManagerModule;
Expand Down Expand Up @@ -56,6 +57,7 @@
SourceCodeModule.class,
TimingModule.class,
UIManagerModule.class,
NativeDevSplitBundleLoaderModule.class,
})
public class CoreModulesPackage extends TurboReactPackage implements ReactPackageLogger {

Expand Down Expand Up @@ -101,7 +103,8 @@ public ReactModuleInfoProvider getReactModuleInfoProvider() {
HeadlessJsTaskSupportModule.class,
SourceCodeModule.class,
TimingModule.class,
UIManagerModule.class
UIManagerModule.class,
NativeDevSplitBundleLoaderModule.class,
};

final Map<String, ReactModuleInfo> reactModuleInfoMap = new HashMap<>();
Expand Down Expand Up @@ -158,6 +161,9 @@ public NativeModule getModule(String name, ReactApplicationContext reactContext)
return createUIManager(reactContext);
case DeviceInfoModule.NAME:
return new DeviceInfoModule(reactContext);
case NativeDevSplitBundleLoaderModule.NAME:
return new NativeDevSplitBundleLoaderModule(
reactContext, mReactInstanceManager.getDevSupportManager());
default:
throw new IllegalArgumentException(
"In CoreModulesPackage, could not find Native module for " + name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ public void loadScriptFromFile(String fileName, String sourceURL, boolean loadSy
jniLoadScriptFromFile(fileName, sourceURL, loadSynchronously);
}

@Override
public void loadSplitBundleFromFile(String fileName, String sourceURL) {
jniLoadScriptFromFile(fileName, sourceURL, false);
}

private native void jniSetSourceURL(String sourceURL);

private native void jniRegisterSegment(int segmentId, String path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,25 @@ public String loadScript(JSBundleLoaderDelegate delegate) {
};
}

/**
* Same as {{@link JSBundleLoader#createCachedBundleFromNetworkLoader(String, String)}}, but for
* split bundles in development.
*/
public static JSBundleLoader createCachedSplitBundleFromNetworkLoader(
final String sourceURL, final String cachedFileLocation) {
return new JSBundleLoader() {
@Override
public String loadScript(JSBundleLoaderDelegate delegate) {
try {
delegate.loadSplitBundleFromFile(cachedFileLocation, sourceURL);
return sourceURL;
} catch (Exception e) {
throw DebugServerException.makeGeneric(sourceURL, e.getMessage(), e);
}
}
};
}

/**
* This loader is used when proxy debugging is enabled. In that case there is no point in fetching
* the bundle from device as remote executor will have to do it anyway.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public interface JSBundleLoaderDelegate {
*/
void loadScriptFromFile(String fileName, String sourceURL, boolean loadSynchronously);

/**
* Load a split JS bundle from the filesystem. See {@link
* JSBundleLoader#createCachedSplitBundleFromNetworkLoader(String, String)}.
*/
void loadSplitBundleFromFile(String fileName, String sourceURL);

/**
* This API is used in situations where the JS bundle is being executed not on the device, but on
* a host machine. In that case, we must provide two source URLs for the JS bundle: One to be used
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,25 @@ public static DebugServerException makeGeneric(
return new DebugServerException(reason + message + extra, t);
}

private final String mOriginalMessage;

private DebugServerException(String description, String fileName, int lineNumber, int column) {
super(description + "\n at " + fileName + ":" + lineNumber + ":" + column);
mOriginalMessage = description;
}

public DebugServerException(String description) {
super(description);
mOriginalMessage = description;
}

public DebugServerException(String detailMessage, Throwable throwable) {
super(detailMessage, throwable);
mOriginalMessage = detailMessage;
}

public String getOriginalMessage() {
return mOriginalMessage;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,7 @@ public void downloadBundleFromURL(
Request.Builder requestBuilder) {

final Request request =
requestBuilder
.url(formatBundleUrl(bundleURL))
.addHeader("Accept", "multipart/mixed")
.build();
requestBuilder.url(bundleURL).addHeader("Accept", "multipart/mixed").build();
mDownloadBundleFromURLCall = Assertions.assertNotNull(mClient.newCall(request));
mDownloadBundleFromURLCall.enqueue(
new Callback() {
Expand Down Expand Up @@ -165,10 +162,6 @@ public void onResponse(Call call, final Response response) throws IOException {
});
}

private String formatBundleUrl(String bundleURL) {
return bundleURL;
}

private void processMultipartResponse(
final String url,
final Response response,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -419,15 +419,26 @@ private boolean getJSMinifyMode() {
}

private String createBundleURL(String mainModuleID, BundleType type, String host) {
return createBundleURL(mainModuleID, type, host, false, true);
}

private String createSplitBundleURL(String mainModuleID, String host) {
return createBundleURL(mainModuleID, BundleType.BUNDLE, host, true, false);
}

private String createBundleURL(
String mainModuleID, BundleType type, String host, boolean modulesOnly, boolean runModule) {
return String.format(
Locale.US,
"http://%s/%s.%s?platform=android&dev=%s&minify=%s&app=%s",
"http://%s/%s.%s?platform=android&dev=%s&minify=%s&app=%s&modulesOnly=%s&runModule=%s",
host,
mainModuleID,
type.typeID(),
getDevMode(),
getJSMinifyMode(),
mPackageName);
mPackageName,
modulesOnly ? "true" : "false",
runModule ? "true" : "false");
}

private String createBundleURL(String mainModuleID, BundleType type) {
Expand All @@ -454,6 +465,11 @@ public String getDevServerBundleURL(final String jsModulePath) {
mSettings.getPackagerConnectionSettings().getDebugServerHost());
}

public String getDevServerSplitBundleURL(String jsModulePath) {
return createSplitBundleURL(
jsModulePath, mSettings.getPackagerConnectionSettings().getDebugServerHost());
}

public void isPackagerRunning(final PackagerStatusCallback callback) {
String statusURL =
createPackagerStatusURL(mSettings.getPackagerConnectionSettings().getDebugServerHost());
Expand Down
Loading

0 comments on commit fca3a39

Please sign in to comment.