Coder Social home page Coder Social logo

vincentriemer / react-native-dom Goto Github PK

View Code? Open in Web Editor NEW
3.3K 72.0 94.0 15.09 MB

An experimental, comprehensive port of React Native to the web.

Home Page: https://rntester.now.sh

License: MIT License

JavaScript 90.73% HTML 7.10% CSS 2.17%
react react-native webworkers native ui-framework

react-native-dom's Introduction

React Native DOM · CircleCI npm version lerna All Contributors

An experimental, comprehensive port of React Native to the web.

  • Multithreaded by default: Following the exact same architecture as React Native on mobile, all of your react components/app logic are run in web worker, leaving the main thread to entirely focus on rendering.
  • Same layout behavior as React Native on mobile: Powered by custom bindings to Yoga and compiled to WebAssembly, avoid layout inconsistencies between your native and web projects.
  • Built with the same bundler used for existing React Native platforms: Build both the "native" main and JS threads with the Metro Bundler along with all the developer experience features it provides.
  • Ecosystem compatible escape hatch to the DOM: Using the same native module bridge, expose DOM-specific APIs in a more generic way that can easily be made into a cross-platform module.

To see it in action, check out these live demos:


Why?

For the best introduction to this project, check out my talk at React Europe 2018 introducing it.


WARNING

This project is still highly experimental and many aspects of it are subject to breaking changes, continue at your own risk.


Getting Started

Getting your React Native project configured to use react-native-dom is a lot like the process for other 3rd party platforms such as react-native-windows.

If you're starting a new project from scratch: ensure you have the react-native CLI installed globally.

npm install -g react-native-cli
# or
yarn global add react-native-cli

Next, initialize your React Native project.

react-native init [project name]

Then, cd into your project and install rnpm-plugin-dom into your devDependencies, after which you can initialize your React Native DOM scaffolding with the react-native dom command.

npm install --save-dev rnpm-plugin-dom
# or
yarn add --dev rnpm-plugin-dom

# Add DOM support to your React Native project
react-native dom

To run your initialized project in your browser, you can either:

  • Start the packager yourself using react-native start and navigate open your browser to localhost:8081/dom
  • Leverage the built-in rnpm command react-native run-dom which will start the packager and open the browser to the correct URL for you

NOTE: After setting up the DOM platform you may need to run react-native start with the --reset-cache flag at least once if you recieve an error message like Unable to resolve module AccessibilityInfo.

Overview of files generated by the RNPM plugin

  • dom/bootstrap.js - Entry point to the main thread bundle where you can set runtime configuration options, register custom native modules, or any other JS initialization you would like to do.
  • dom/entry.js - Entry point to the JS thread bundle, will likely only be importing your App's entry point from the top-level folder of your project.
  • dom/index.html - HTML file which is what references and loads the JS bundles.
  • (conditionally) rn-cli.config.js - Depending on if the project already has one, the rnpm plugin will either create it with the proper configuration options to support the DOM platform or will simply add the necessary entries to your existing one.

React Developer Tools

You can use the standalone version of React Developer Tools to debug the React component hierarchy. To use it, install the react-devtools package globally:

npm install -g react-devtools

Now run react-devtools from the terminal to launch the standalone DevTools app:

react-devtools

In order to activate the connection with the devtools app add '?devtools' to the end of your development url (e.g. localhost:8081/dom?devtools)

Building for Production

A built-in script for performing a production build is still in the backlog but here is a manual script which does so (assuming the same directory structure that gets generated from the rnpm plugin).

# Ensure development-speecific code is stripped from the bundle
export NODE_ENV=production

# Make the dist directory, or the build command below will fail.
mkdir -p ./dom/dist

# Build the main thread bundle
react-native bundle \
  --config $(pwd)/rn-cli.config.js \
  --dev false \
  --platform dom \
  --entry-file ./dom/bootstrap.js \
  --assets-dest ./dom/dist \
  --bundle-output ./dom/dist/bootstrap.bundle

# Build the JS thread bundle
react-native bundle \
  --config $(pwd)/rn-cli.config.js \
  --dev false \
  --entry-file ./dom/entry.js \
  --platform dom \
  --bundle-output ./dom/dist/entry.bundle \
  --assets-dest ./dom/dist

# Copy the index.html file to the build destination
cp dom/index.html dom/dist/index.html

The resulting folder in dom/dist will contain static HTML & JS ready to be deployed to your provider of choice.


Writing Native Modules/Views

Work In Progress

The API for this is going to be overhauled soon with accompanying documentation. If you want to see what it currently looks like take a look at some of the built in native modules such as AsyncLocalStorage


Repository Structure

This project is a lerna-managed monorepo with all the projects living in the packages folder.

Package Overview

  • react-native-dom - The library itself (this is most likely the package you're interested in).
  • rnpm-plugin-dom - RNPM plugin primarily used for bootstrapping DOM support into a React Native project.
  • rndom-* - Custom web components (built with svelte) used for some of the built-in widgets/views in react-native-dom.

One noticeable omission to the list of packages is the custom build of Yoga which can be found in this separate repo. yoga-dom is not included in this monorepo due to requiring a significantly different build environment than this repo's entirely JS codebase.


Running RNTester/Examples

To run the examples located in the react-native-dom source, run the following commands from the root of the monorepo:

# be sure to update the git submodules to pull the RNTester code
git submodule update --init

# install dependencies
yarn && yarn compile

# start the react-native packager
yarn run-examples

Then navigate to localhost:8081/Examples and choose which example you would like to see.

A live deployment of the RNTester project (used primarily for manually testing changes) can be found at rntester.now.sh

Contributors

Thanks goes to these wonderful people (emoji key):


Vincent Riemer

💻 🐛 📖 💡 🤔 🚇 📦 📢

Joe Goodall

📖

François Rosato

📖

Moti Zilberman

💻 📖

thebetterjort

📖

Bilo Lwabona

📖

Madhav Varshney

📖

Eric Rozell

💻

empyrical

💻

This project follows the all-contributors specification. Contributions of any kind welcome!

react-native-dom's People

Contributors

iamralpht avatar jayphelps avatar joegoodall1 avatar madhavarshney avatar motiz88 avatar nicosommi avatar tbergman avatar thebetterjort avatar vincentriemer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-dom's Issues

Text measurement

I know it's too early for speed optimizations, just wanted to point out some way of doing so for text measurement, because it's what runs frame rate in the app right now (it forces browser layout).

So the more optimized way for main thread might measuring with <canvas>'s 2d context's measureText() API. Which measure itself most likely won't be any faster, it won't be causing any forced layout issues in the DOM.

For the off-thread measurement, OffscreenCanvas probably can be used, once it's implemented and supports 2d context rendering.

Just wanted to file this issue so it could be tracked by others or additional thoughts added.

Great work! 🎉

Wow 🔥

This is the most exciting project for me in web dev since React was first released. Amazing work, thank you for this!

History navigation support

React native don't need to handle url and history navigation, but web need that feature. It would be great if react-native-dom have mechanism to handle and implement history navigation.

Example Usecase:
In the movie example app, visit the movie detail pages. Refresh the page. The Expected behaviour should be stay on the movie detail page. But since react-native-dom don't have url handler, it back to home screen.

No version of 'react-native-dom' found that satisfies a peer dependency on '[email protected]'

When use "$: react-native dom"
Appears:
No version of 'react-native-dom' found that satisfies a peer dependency on '[email protected]'

This is my package.json:

{
"name": "dom",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.4.1",
"react-dom": "^16.4.1",
"react-native": "0.56.0",
"react-native-dom": "0.2.0"
},
"devDependencies": {
"babel-jest": "23.4.0",
"babel-preset-react-native": "^5",
"jest": "23.4.1",
"react-test-renderer": "16.4.1",
"rnpm-plugin-dom": "^0.1.1"
},
"jest": {
"preset": "react-native"
}
}

Document Asset Handling

It looks like the way to use custom fonts is to add a link in the index.html. It would be nice if there were a mechanism to link and load them as first-class resources like you can on iOS and Android. I'm not sure how other asset types are handled here.

unable to run examples

unable to run examples

Cannot set property 'getCurrentStack' of undefined

Object.setCurrentFiber
    ReactNativeRenderer-dev.js:5317:2
performUnitOfWork
...

Support Expo

Hi,

This would be awesome if the Expo hello world app would be easy to deploy as a website, making the dom RN platform more accessible without having to eject, install plugin, setup configuration etc...

Also many of us already have Expo non-ejected apps and it would be nice to be able to test RN-dom on it without ejecting.

I guess this also needs support from Expo team to work and it's not only on your side, just opening the issue to see if there is interest for this and track eventual progress.

See also Canny request

TypeError: Cannot read property 'injection' of undefined

Modules in use:
"react": "^16.5.2",
"react-dom": "^16.5.2",
"styled-components": "^3.4.9"

It looks like issue depended on react-native-dom. I'm using style-components/primitives that uses react-primitives that uses react-native-dom.

screen shot 2018-10-07 at 12 50 13 pm

Displaying MapView

Do you have any idea how to display MapView in react native dom? should we create native modules?

Move Yoga layout to a separate thread

The major blocker to accomplishing this is that the measure function used primarily for measuring text is synchronous. First idea to try out is to hack together a way to sync-ify the call using while loops and setTimeout.

Another unknown concern is how making the layout async will affect the stability of rendering. It is likely some sort of "locking" functionality will need to be added. Layout performance itself will likely not be improved through the change but considering the the "Native" driven animations are on the main thread they currently can be stalled/blocked by an expensive layout calculation.

Overhaul Native Module/ViewManager Decorators

Blocked by babel/babel#7542, facebook/metro#92

Currently the decorators used for exposing modules/methods/view properties are utilizing the deprecated decorators babel transform and should be migrated to the spec and the new transform. This should be an opportunity to revisit the actual naming and functionality of the decorators, for example add commonly used value transformations like view style props that accept colors (need to convert from number to rgba values)

Apple Pencil not working with the demos

Apple Pencil doesn’t work with the demos for some reason. Pencil works just like a finger in Safari so this seems to be ignoring some input events.

Not a high priority issue by any means but would be nice to have this working at some point because many people use Pencil with bigger iPads as a general purpose pointer and page or app that doesn’t work with it is a bit frustrating experience.

Live reloading

First congratulations, this is an amazing project. Is there a way to live or hot reload the dom app in development?

Expo support

Hello, i'm trying to run my react-native-scripts project and have the issues.
First, the command run the, (review the node package)
react-native run-dom --port=19000, but he don't recognize this option
But i can run the packager on 8081 port

Second, i'm not sure that is related with first issue. When i'm starting
i've the error:
bundling failed: Error: Unable to resolve module "./BarCodeScanner" from "/node_modules/expo/src/Expo.js": The module "./BarCodeScanner" could not be found from "node_modules/expo/src/Expo.js". Indeed, none of these files exist:
In Expo BarCodeScanner we have the file with extension BarCodeScanner.web.js, so it is good to support compilation for this one.

Is Redux unusable in react-native-dom?

When I tried it, no error occurred, but no data came to props.

I did the following.
・Change Provider to what is provided from react-redux
・Pass store to Provider

I thought that it was not necessary to do particularly difficult things, but is it necessary to do something?

import * as React from 'react';
import { Dimensions } from 'react-native';
import { Provider } from 'react-redux';
import configureStore from '../redux/configureStoreForWeb';
import loadTranslations from '../i18n/translations';

const store = configureStore();

const { Consumer } = React.createContext({ width: 0, height: 0 });

loadTranslations();

class DimensionsProvider extends React.Component {
  constructor(props) {
    super(props);
    this.state = this.getDimensions();
  }

  getDimensions() {
    const { width, height } = Dimensions.get('window');
    return { width, height };
  }

  updateDimensions = () => {
    this.setState(this.getDimensions());
  };

  componentDidMount() {
    Dimensions.addEventListener('change', this.updateDimensions);
  }

  componentWillUnmount() {
    Dimensions.removeEventListener('change', this.updateDimensions);
  }

  render() {
    const { children } = this.props;
    return (
      <Provider value={this.state} store={store}>
        {children}
      </Provider>);
  }
}

export default { Provider: DimensionsProvider, Consumer };

TextInput support

The TextInput component seems to be partially implemented. I can see that an input element is rendered but it's impossible to focus and edit it.

(btw, congrats for the impressive work!)

NativeModules bootstrap example

Spectacular work leveraging custom components, web assembly and the gamut of technologies in creating react-native dom 👏

I'm trying this out on our production app which uses a number of native packages such as react-native-device-info. I noticed mention of native modules in the bootstrap file:

const ReactNativeDomOptions = {
  enableHotReload: false,
  nativeModules: []
};

For the time being, I'd like to shim the native modules as empty fillers to get past the first wave of errors. What's the best way to use the nativeModules feature?

Logo Contribution

Hi
I just saw your app and if you need a new logo or widget design i can help you
You can tell me what kind of a logo do you want
I am waiting for you reply

Map .dom.js to .web.js

Hello,

I know RNDom is incompatible to RNW, but for the most of the project files in my project I don't have a difference between DOM and WEB. Is there a configuration way (maybe in the rn-cli.config.js?) to take the .web.js file if there is no .dom.js?

In the meantime I have to duplicate all .web.js files to .dom.js files.

Thank you

Tech Talk

I read someone that there was a talk given on this but now I can't find it for the life of me. Does anybody have a link?

Implement NativeViewHierarchyOptimizer

On Android, RN will skip mounting views if they are only used for layout which boosts performance. RNDom struggles with really deep view hierarchies so it would be worth implementing as well. The one caveat would be this would likely also require changes in the LayoutAnimationManager implementation as well as it changes the mapping of shadow nodes to views.

The Android implementation can be found here: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyOptimizer.java

WebView ‘Send message’ button is not clickable

Reproducing :
RNTester -> WebView -> Messaging Text Example:
The ‘Send message’ buttons are not clickable, both in the WebView side and in the React Native side.
The cause might be the value of the pointer-events prop whose value is ‘unset’ in the
‘ui-child-container-view’ components.
Changing the pointer-events prop value to ‘auto’ in the iframe parent component (‘ui-child-container-view’ ) makes the button in the WebView side clickable.

Flex layout not consistent with native device layouts

I'm aware of the "it's not ready for production" caveat, but I wanted to kick the tires and play with this lib a bit. I added react-native-dom to an application I'm working on, and I'm seeing some issues with layout. The layout in RNDom isn't matching iOS or Android, so I'm guessing there's something janky in how Yoga is being applied.

In this example, each row has two children, one for the title and one for this magnitude bar. The title is flex: 2 and the magbar is flex: 1. The RNDom version has inconsistent sizings from row-to-row.

Layout on iOS
Layout on react-native-dom

Support Image resizeMode=repeat

Opening this issue so I can claim it and make it my first contribution to this intriguing project :)

I'd like to use this as a jumping-off point to get to know the codebase. I've recently built the corresponding feature in React Native Android so am reasonably confident I can make this feature happen here.

WebView messaging errors

Reproducing :
RNTester -> WebView -> Messaging Text Example:
(The ‘Send message’ buttons are not clickable (please see issue #85)
As a temp fix to make the ‘Send message to React Native’ button clickable, I changed the pointer-events prop of the parent component of the iframe (ui-child-container-view) from ‘unset’ to ‘auto’)
When I click on it I get the following error:
"Uncaught TypeError: Failed to execute 'postMessage' on 'Window': No function was found that matched the signature provided.
at HTMLButtonElement."
I also got an error when clicking on the ‘Send Message to Web View’ but currently can't reproduce it.
I couldn’t get this to work when running another React Native demo app with a WebView - getting similar errors.

Set CSP or Firefox fails to load (301)

Looks like this resource is failing and Firefox shows blank page on https://rntester.now.sh, Windows 10 64bit.

CURRENT_SITE: rntester.now.sh
KeeperFill-var.js:17245:51
Running application "RNTesterApp" with appParams: {"rootTag":1,"initialProps":{}}. DEV === false, development-level warning are OFF, performance optimizations are ON
RNTesterApp.dom.bundle:257:72
Loading mixed (insecure) display content “http://origami.design/public/images/bird-logo.png?r=1&t=1532364279564” on a secure page[Learn More]

Adopt CSS Typed OM API for Internal Styling

Moving to the CSS Typed OM API instead of what is currently done with just the style property on HTMLElements should improve both styling performance (no need to serialize styles to a string just to have the browser parse that string to apply it) and maintainability with a more structured/typed API.

It may be a tad to early to start work but it could be started soon as https://github.com/csstools/css-typed-om stabilizes.

ENOENT: no such file or directory, open './dom/dist/entry.bundle'

react-native bundle \
>   --config $(pwd)/rn-cli.config.js \
>   --dev false \
>   --entry-file ./dom/entry.js \
>   --platform dom \
>   --bundle-output ./dom/dist/entry.bundle \
>   --assets-dest ./dom/dist

I fixed this error by creating the dom folder by hand. Do I need to run this command with sudo?

Writing full page component

We have an exiting PWA, there are some routes that render components using RNW.

Is it possible to write an NPM module that is a full page size component and import in an existing PWA and run it using RND?
Or, differently put how to integrate with an existing PWA such that few pages render with RND?

RCTModalHostView for Modals

I'm starting work on RCTModalHostView because our app uses Modals and it should be relatively straight-forward to add. What's the easiest way to build the react-native-dom project for local development?

Any tips on how to best implement this would also be appreciated.

Demos/examples not working on iOS/Safari

This project is so cool! Nice work!

The examples only work on my Mac - when I try to visit rntester.now.sh on my phone (Safari on iPhone 6), I see the following errors in the console:

image

Guide for creating new components

Is there any kind of guide that covers how to implement a "native view" for react-native-dom? I'd like to build a component to expose the html5 video tag.

I've looked at the ImageView implementation, but am not very familiar with the react-native-dom model to know what's going on there. I can debug my way through it but was hoping there was an easier way.

Hard time understanding the use case for this

Maybe I'm a bit behind in web trends and totally missing the point, I have a few questions someone may be able to answer.

Q1. What is the point of a mobile framework being ported to web?
Q2. Why aren't we just optimizing react.js for the web?
Q3. It feels like we are confusing the frontend landscape with even more frameworks, like my previous question - why not just contribute to react.js...
Q4. Don't we have electron + react.js for web to native desktop experience? What is the purpose of this?

Create a Roadmap

Project needs a roadmap.

  • Spectrum Chat
  • Writing (I’m learning and writing on medium)
  • lower bundle size (>500kb gzipped)
  • Treeshaking

Throwing these out there.

Integration with React Developer Tools

Hi Vincent,
Thanks a lot for this incredible project!
What needs to be done to view the React component tree in one of the following and how can I help? :

  • Standalone React Developer Tools / React Native Debugger
  • React Devtools Chrome extension

Share API - user action requirement

I'm trying to implement the RN Share API on top of the Web Share API. The latter is not available inside workers and must be triggered by user activation, so from my tests neither the "JS" nor the "native" Share module can actually successfully invoke it.

The limitation seems to be inherent to the use of a worker+bridge to route user actions to API calls of this sort, which is interesting because this situation will in all likelihood repeat itself with other Web APIs (e.g. audio, probably?). Therefore I wonder if there is anything RNDom can do about this architecturally or whether we need new browser-level hooks to solve this. (Or a different kind of escape hatch in the short term - e.g. the ability to attach synchronous event handlers to certain views as needed, bypassing the bridge)

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.