GithubHelp home page GithubHelp logo

intfrr / react-native-renderer Goto Github PK

View Code? Open in Web Editor NEW

This project forked from angular/react-native-renderer

0.0 3.0 0.0 134.85 MB

An angular 2 renderer for react native

License: Apache License 2.0

JavaScript 23.77% Shell 10.19% TypeScript 66.03%

react-native-renderer's Introduction

Build Status

Todo app demo on rnplay.org

This project is an Angular 2 renderer that renders to iOS. It replaces the usual DOM renderer in Angular 2 with a custom renderer that renders through React Native.

Getting Started

If you're looking to install this through npm, see the readme on the npm package sources.

You need a Mac with XCode and node. After cloning the repo, run:

npm install

If you are having issues with tsd, run tsd rate to make sure you are not being rate limited by GitHub. If you see a 0/60, then you need to add a GitHub OAuth token with tsd token. More information can be found on the tsd repo.

Then initialize an example:

# usage: gulp init <example>
gulp init todoApp

When modifying the example (src/EXAMPLE_NAME/) or the renderer (src//*.ts), update by running:

# usage: gulp build <example>
gulp build todoApp

# OR
# usage gulp watch <example>
gulp watch todoApp

To run the example:

# usage: gulp open <example>
gulp open todoApp

# click the "run" button in XCode

To run tests:

./scripts/build_and_test.sh

react-native-renderer

This codebase is a hack that attempts to take the "React" part of React Native and replace it with Angular 2. I say that it is a hack because some of the details of React Native described here are not documented in the React Native docs and are subject to change. Also, everything here about how React Native works is just how I think it works, after some experimentation.

React Native Renderer replaces the Dom Renderer

React Native without React

Internal modules can't be required this way in the future. See facebook/react-native#1821

React Native projects usually require('react-native') and then React.AppRegistry.registerComponent. To create an app without React, just require('AppRegistry') directly, and AppRegistry.registerRunnable instead. React Native also exposes NativeModules which provides access to native views through NativeModules.UIManager. Combine these to create a simple a "Hello World" application:

//index.ios.js
var AppRegistry = require('AppRegistry');
var NativeModules = require('NativeModules');
var UIManager = NativeModules.UIManager;

AppRegistry.registerRunnable('ProjectName', function() {
	// create views
	UIManager.createView(2, "RCTView", null, {});
	UIManager.createView(3, "RCTText", null, {});
	UIManager.createView(4, "RCTRawText", null, {
		"text": "Hello World!"
	});

	// attach views
	// Note: the "root" native view is tag # 1
	UIManager.manageChildren(1, null, null, [2], [0], null);
	UIManager.manageChildren(2, null, null, [3], [0], null);
	UIManager.manageChildren(3, null, null, [4], [0], null);
});

The AppRegistry always has to be required first, as it requires certain modules in the right order, and sets up polyfills for functions like setTimeout. After requiring it, any other module provided by React Native can be included without issue. registerRunnable allows React Native to start your application when the native side is ready.

Angular 2 in JavaScriptCore

To run in JavaScriptCore, Angular 2 needs traceur-runtime, a DOM implementation to parse templates with (parse5), and properly patched async functions with zonejs.

...you'll also notice es6-shim included in the project. This is to fix some issue with Maps. Ideally this is not needed.

traceur-runtime

Easy.

require('traceur/bin/traceur-runtime.js');

parse5

JavaScriptCore has no DOM. This is fixed with a couple lines of code:

import { Parse5DomAdapter } from 'angular2/src/dom/parse5_adapter';

Parse5DomAdapter.makeCurrent();

This is almost sufficient, but in this renderer, templates don't use elements like <div> and <span>. They React Native elements like <Text> and <View>. The parse5 adapter is fine with custom tag names (just like HTML5 is), but it will still verify element properties. Ideally, the definitions of each element would be defined, the parse5 adapter could tell which properties are on which elements. Instead, this project just checks to make sure that a property is ANY valid React Native element property by replacing the parse5 adapter's hasProperty:

class CustomParse5DomAdapter extends Parse5DomAdapter {
	static makeCurrent() { setRootDomAdapter(new CustomParse5DomAdapter()); }
	hasProperty(element, name: string): boolean {
		console.log(name);
		return RCT_PROPERTY_NAMES[name] !== undefined;
	}
}

CustomParse5DomAdapter.makeCurrent();

The parse5 adapter also uses the Node APIs url and css, which need to be patched before including the parse5 adapter.

Angular2's parse5 adapter uses parse5, but angular2 does not have it listed in its dependencies. Parse5 must be npm installed.

zonejs

zonejs needs a custom patch for React Native. This could be done through patching the polyfilled setTimeout-like functions and Promises. An easier (and faster) way to do it is to just patch the source of all async calls, which seems to be ReactUpdates.batchedUpdates. This needs to be patched on Angular's zone:

bootstrap( ... ).then(function(appRef) {
	var zone = appRef._injector.get(NgZone)._innerZone;
	require('ReactUpdates').batchedUpdates = zone.bind(require('ReactUpdates').batchedUpdates);
});

Any time the native side calls into JS, the application code will run, then zonejs will run detectChanges, and the results will then be returned to the native side.

Evaluation

This project was tested on the iPhone Simulator, an iPhone 4, and an iPad 2.

animations

There are 2 .mp4 files in the video branch, demoing the app on the iPad and iPhone.

On the iPad, most animations almost feel native.

On the iPhone, many animations are slow, and gain an increasing delay over time. The animations in objective-c (react-native's LayoutAnimation) are still fairly fast.

startup times

These are estimates, based on only a few logs.

On the iPhone 4:

3 - 3.5s blocked on JS
	350ms on AppRegistry require
	150ms on es6-shims
	600ms on Parse5DomAdapter (the first angular2 require)
	100ms on traceur-runtime
	800ms requiring bind, Renderer, bootstrap from angular2
		600ms between bootstrap call and promise callback
		200ms in the first processBatch
		300ms between promiseBatch end and createRootHostView start
		40ms
		70ms spent on detectChanges
	800ms between first and second processBatch
		not sure what’s happening here... maybe React and/or React Native is being initialized?
~7s from tapping app to visible UI
	~2s to go from tap (and black screen) to white screen w/fps
	~5s to see UI

potential further development

react-native-renderer's People

Contributors

igorminar avatar uber5001 avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.