Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bridge] Pass __fbBatchedBridgeConfig into the bundle instead of making it global #62

Closed
ide opened this issue Feb 13, 2015 · 3 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@ide
Copy link
Contributor

ide commented Feb 13, 2015

This is to reduce globals and encourage scoping. A specific approach I have in mind is to make the bundle produce a function that takes the bridge config as an argument:

(function(batchedBridgeConfig) {
// current bundle code here
});
// source map stuff

And when setting up ReactKit:

// get the js context from the executor -- API for this needs to be thought out
[[context evaluateScript:bundleScriptString] invokeWithArguments:@[configObject]]

Then the global goes away and you don't need -[RCTJavaScriptExecutor injectJSONText:asGlobalObjectNamed:callback:] either!

@frantic
Copy link
Contributor

frantic commented Feb 16, 2015

I think it's a very clever idea and I like reducing RCTJavaScriptExecutor protocol. However, the code in the bundle has to define a global require function that will be used by ObjC to invoke JS methods. Also there are benefits for the existing model, for example Chrome debugger integration (not in the oss repo yet) that runs the JS code in a Chrome page. The app bundle in this case is loaded via <script> tag instead of being passed via websockets.

@ide
Copy link
Contributor Author

ide commented Feb 16, 2015

Could the JS application engine be set up by passing in a global object? For example:

(function(global) {
  // Make require.js use "global", which passes it to all of the module factory functions.
  // require.js also sets "global.require", "global.requireLazy", etc...
});

From the native side, the application engine is initialized like:

// Create a "global" object. May need to have it act as a proxy to the real global object
// and would need to write a little more code for that.
JSValue *reactGlobal = [JSValue valueWithNewObjectInContext:context];
reactGlobal[@"__fbBatchedBridgeConfig"] = bridgeConfigDictionary;
[[context evaluateScript:bundleScriptString] callWithArguments:@[reactGlobal]];

Accessing the global require function from Obj-C is simple as well:

JSValue *exports = [reactGlobal[@"require"] callWithArguments:@[@"moduleName"]];
[exports invokeMethod:@"doSomething" withArguments:@[...]];

So in the end, RCTJavaScriptExecutor has a smaller API and ReactKit is better encapsulated by reducing pollution of the global scope (some functions like setTimeout need another approach though).


For the Chrome debugger extension, it might be possible to keep using the real global object with the help of the packager by serving (function(global) { /* ... */ })(window);.

@brentvatne brentvatne changed the title Pass __fbBatchedBridgeConfig into the bundle instead of making it global [Bridge] Pass __fbBatchedBridgeConfig into the bundle instead of making it global May 31, 2015
@sahrens
Copy link
Contributor

sahrens commented Jun 12, 2015

Closing for now since it doesn't sound like this is blocking anything.

@sahrens sahrens closed this as completed Jun 12, 2015
@facebook facebook locked as resolved and limited conversation to collaborators Jun 12, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 23, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

4 participants