mirror of
https://github.com/zhigang1992/react-native-web.git
synced 2026-01-12 09:24:17 +08:00
3
.github/ISSUE_TEMPLATE/bug.md
vendored
3
.github/ISSUE_TEMPLATE/bug.md
vendored
@@ -33,6 +33,9 @@ Steps to reproduce:
|
||||
**Expected behavior**
|
||||
<!--
|
||||
REQUIRED: A clear and concise description of what you expected to happen.
|
||||
|
||||
Please check that the behaviour is not expected React Native behaviour by
|
||||
running your test case on iOS or Android using https://snack.expo.io.
|
||||
-->
|
||||
|
||||
**Environment (include versions). Did this work in previous versions?**
|
||||
|
||||
217
README.md
217
README.md
@@ -25,7 +25,7 @@ using Node.js.
|
||||
Who is using React Native in production web apps?
|
||||
[Twitter](https://mobile.twitter.com), [Major League
|
||||
Soccer](https://matchcenter.mlssoccer.com),
|
||||
[Flipkart](https://www.flipkart.com/), Playstation, Uber, [The
|
||||
[Flipkart](https://www.flipkart.com/), Uber, [The
|
||||
Times](https://github.com/newsuk/times-components).
|
||||
|
||||
Browser support: Chrome, Firefox, Edge, Safari 7+, IE 10+.
|
||||
@@ -38,34 +38,56 @@ The easiest way to get started is to edit this
|
||||
anything to try it out.
|
||||
|
||||
For installation and configuration details please read the [getting
|
||||
started](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/getting-started.md)
|
||||
started](https://github.com/necolas/react-native-web/blob/master/docs/guides/getting-started.md)
|
||||
guide.
|
||||
|
||||
## Documentation
|
||||
|
||||
You can find the API documentation [on the website][website-url].
|
||||
|
||||
Please refer to the [React Native documentation][react-native-url] for more
|
||||
design details, and for information about the [Gesture Responder
|
||||
Please refer to the [React Native documentation][react-native-url] for the
|
||||
overall API, design details, and information about the [Gesture Responder
|
||||
system](https://facebook.github.io/react-native/docs/gesture-responder-system.html)
|
||||
and [animations](https://facebook.github.io/react-native/docs/animations.html).
|
||||
|
||||
Some components and APIs are extended with additional features for the web. And
|
||||
in a few cases, features present for Android or iOS are missing on the web.
|
||||
These differences are documented [on the website][website-url].
|
||||
|
||||
### Guides
|
||||
|
||||
* [Getting started](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/getting-started.md)
|
||||
* [Style](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/style.md)
|
||||
* [Accessibility](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/accessibility.md)
|
||||
* [Internationalization](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/internationalization.md)
|
||||
* [Direct manipulation](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/direct-manipulation.md)
|
||||
* [Experimental / unstable use](https://github.com/necolas/react-native-web/blob/master/packages/website/guides/advanced.md)
|
||||
These guides provide a detailed look at using React Native to create accessible
|
||||
web experiences. Certain web-specific patterns are documented in the "web
|
||||
recipes" guide.
|
||||
|
||||
* [Getting started](https://github.com/necolas/react-native-web/blob/master/docs/guides/getting-started.md)
|
||||
* [Client-side rendering](https://github.com/necolas/react-native-web/blob/master/docs/guides/client-side-rendering.md)
|
||||
* [Server-side rendering](https://github.com/necolas/react-native-web/blob/master/docs/guides/server-side-rendering.md)
|
||||
* [Style](https://github.com/necolas/react-native-web/blob/master/docs/guides/style.md)
|
||||
* [Accessibility](https://github.com/necolas/react-native-web/blob/master/docs/guides/accessibility.md)
|
||||
* [Internationalization](https://github.com/necolas/react-native-web/blob/master/docs/guides/internationalization.md)
|
||||
* [Direct manipulation](https://github.com/necolas/react-native-web/blob/master/docs/guides/direct-manipulation.md)
|
||||
* [Web recipes](https://github.com/necolas/react-native-web/blob/master/docs/guides/web-recipes.md)
|
||||
* [Multi-platform apps](https://github.com/necolas/react-native-web/blob/master/docs/guides/multi-platform-apps.md)
|
||||
* [Experimental / unstable use](https://github.com/necolas/react-native-web/blob/master/docs/guides/advanced.md)
|
||||
|
||||
## Integrations
|
||||
|
||||
Examples of using React Native for Web with other web tools:
|
||||
|
||||
* [Docz](https://github.com/pedronauck/docz/tree/master/examples/react-native-flow)
|
||||
* [Gatsby](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-react-native-web)
|
||||
* [Next.js](https://github.com/zeit/next.js/tree/master/examples/with-react-native-web)
|
||||
* [Phenomic](https://github.com/phenomic/phenomic/tree/master/examples/react-native-web-app)
|
||||
* [Razzle](https://github.com/jaredpalmer/razzle/tree/master/examples/with-react-native-web)
|
||||
* [Storybook](https://github.com/necolas/react-native-web/tree/master/packages/website/storybook/.storybook)
|
||||
* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/master/examples/react-native)
|
||||
|
||||
## Examples
|
||||
|
||||
There are examples [on the website][website-url] ([source
|
||||
code](https://github.com/necolas/react-native-web/blob/master/packages/website).
|
||||
And all the [React Native examples][examples-url] ([source
|
||||
code](https://github.com/necolas/react-native-web/blob/master/packages/examples))
|
||||
are also available. Here is an example to get you started:
|
||||
Check out all the [React Native examples][examples-url] ([source
|
||||
code](https://github.com/necolas/react-native-web/blob/master/packages/examples)).
|
||||
There are more examples [on the website][website-url] ([source
|
||||
code](https://github.com/necolas/react-native-web/blob/master/packages/website)).
|
||||
And here is a simple example to get you started:
|
||||
|
||||
```js
|
||||
import React from 'react';
|
||||
@@ -96,104 +118,87 @@ You'll notice that there is no reference to `react-dom`; the `App` component is
|
||||
defined using the platform-agnostic APIs and Components introduced by React
|
||||
Native. This allows the app to be rendered to web and native platforms.
|
||||
|
||||
## Integrations
|
||||
|
||||
Examples of using React Native for Web with other web tools:
|
||||
|
||||
* [Gatsby](https://github.com/gatsbyjs/gatsby/tree/master/examples/using-react-native-web)
|
||||
* [Next.js](https://github.com/zeit/next.js/tree/master/examples/with-react-native-web)
|
||||
* [Phenomic](https://github.com/phenomic/phenomic/tree/master/examples/react-native-web-app)
|
||||
* [Razzle](https://github.com/jaredpalmer/razzle/tree/master/examples/with-react-native-web)
|
||||
* [Storybook](https://github.com/necolas/react-native-web/tree/master/packages/website/storybook/.storybook)
|
||||
* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/master/examples/react-native)
|
||||
|
||||
Example recipes for web-specific UI patterns:
|
||||
|
||||
* [Links](https://codesandbox.io/s/53r88k5opx)
|
||||
* [Hover styles](https://codesandbox.io/s/o9q8vy70l5)
|
||||
* [Root element styles](https://codesandbox.io/s/52x1871vjl)
|
||||
|
||||
## Compatibility with React Native
|
||||
|
||||
React Native v0.55
|
||||
|
||||
### Components
|
||||
|
||||
| Name | Status | Notes |
|
||||
| :----------------------- | :------------------ | :---- |
|
||||
| ActivityIndicator | Available | |
|
||||
| ART | Available | |
|
||||
| Button | Available | |
|
||||
| CheckBox | Available | |
|
||||
| FlatList | Available | |
|
||||
| Image | Available (partial) | Missing multiple sources and HTTP headers. |
|
||||
| ImageBackground | Available | |
|
||||
| KeyboardAvoidingView | Available (mock) | |
|
||||
| ListView | Available | |
|
||||
| Modal | Not started | |
|
||||
| Picker | Available | |
|
||||
| RefreshControl | Not started | |
|
||||
| SafeAreaView | Available | |
|
||||
| ScrollView | Available (partial) | Missing momentum scroll events. |
|
||||
| SectionList | Available | |
|
||||
| Slider | Not started | |
|
||||
| StatusBar | Mock | |
|
||||
| SwipeableFlatList | Available | |
|
||||
| SwipeableListView | Available | |
|
||||
| Switch | Available | |
|
||||
| Text | Available (partial) | Missing `onLongPress` support. |
|
||||
| TextInput | Available (partial) | Missing rich text features and auto-expanding behaviour. |
|
||||
| Touchable | Available | Includes additional support for mouse and keyboard interactions. |
|
||||
| TouchableHighlight | Available | |
|
||||
| TouchableNativeFeedback | Not started | |
|
||||
| TouchableOpacity | Available | |
|
||||
| TouchableWithoutFeedback | Available | |
|
||||
| View | Available | |
|
||||
| VirtualizedList | Available | |
|
||||
| WebView | Not started | |
|
||||
| YellowBox | Mock | |
|
||||
| Name | Status | Notes |
|
||||
| :----------------------- | :----- | :---- |
|
||||
| ActivityIndicator | ✓ | |
|
||||
| ART | ✓ | |
|
||||
| Button | ✓ | |
|
||||
| CheckBox | ✓ | |
|
||||
| FlatList | ✓ | |
|
||||
| Image | ✓ | Missing multiple sources ([#515](https://github.com/necolas/react-native-web/issues/515)) and HTTP headers ([#1019](https://github.com/necolas/react-native-web/issues/1019)). |
|
||||
| ImageBackground | ✓ | |
|
||||
| KeyboardAvoidingView | (✓) | Mock. No equivalent web APIs. |
|
||||
| ListView | ✓ | |
|
||||
| Modal | ✘ | Not started ([#1020](https://github.com/necolas/react-native-web/issues/1020)). |
|
||||
| Picker | ✓ | |
|
||||
| RefreshControl | ✘ | Not started ([#1027](https://github.com/necolas/react-native-web/issues/1027)). |
|
||||
| SafeAreaView | ✓ | |
|
||||
| ScrollView | ✓ | Missing momentum scroll events ([#1021](https://github.com/necolas/react-native-web/issues/1021)) and `pagingEnabled` ([#1057](https://github.com/necolas/react-native-web/issues/1057)). |
|
||||
| SectionList | ✓ | |
|
||||
| Slider | ✘ | Not started ([#1022](https://github.com/necolas/react-native-web/issues/1022)). |
|
||||
| StatusBar | (✓) | Mock. No equivalent web APIs. |
|
||||
| SwipeableFlatList | ✓ | |
|
||||
| SwipeableListView | ✓ | |
|
||||
| Switch | ✓ | |
|
||||
| Text | ✓ | Missing `onLongPress` ([#1011](https://github.com/necolas/react-native-web/issues/1011)) and `numberOfLines` ([#13](https://github.com/necolas/react-native-web/issues/13)) support. |
|
||||
| TextInput | ✓ | Missing `onContentSizeChange` ([#793](https://github.com/necolas/react-native-web/issues/793)), rich text features ([#1023](https://github.com/necolas/react-native-web/issues/1023)), and auto-expanding behaviour ([#795](https://github.com/necolas/react-native-web/issues/795)). |
|
||||
| Touchable | ✓ | Includes additional support for mouse and keyboard interactions. |
|
||||
| TouchableHighlight | ✓ | |
|
||||
| TouchableNativeFeedback | ✘ | Not started ([#1024](https://github.com/necolas/react-native-web/issues/1024)). |
|
||||
| TouchableOpacity | ✓ | |
|
||||
| TouchableWithoutFeedback | ✓ | |
|
||||
| View | ✓ | |
|
||||
| VirtualizedList | ✓ | |
|
||||
| WebView | ✘ | Not started ([1025](https://github.com/necolas/react-native-web/issues/1025)). |
|
||||
| YellowBox | (✓) | Mock. No YellowBox functionality. |
|
||||
|
||||
### Modules
|
||||
|
||||
| Name | Status | Notes |
|
||||
| :----------------------- | :------------------ | :---- |
|
||||
| AccessibilityInfo | Mock | No equivalent web APIs. |
|
||||
| Alert | Not started | |
|
||||
| Animated | Available | Missing `useNativeDriver` support. |
|
||||
| AppRegistry | Available | Includes additional support for SSR with `getApplication`. |
|
||||
| AppState | Available | |
|
||||
| AsyncStorage | Available | |
|
||||
| BackHandler | Mock | No equivalent web APIs. |
|
||||
| CameraRoll | Not started | No equivalent web APIs. |
|
||||
| Clipboard | Available | |
|
||||
| ColorPropType | Available | |
|
||||
| DeviceInfo | Available (partial) | |
|
||||
| Dimensions | Available | |
|
||||
| Easing | Available | |
|
||||
| EdgeInsetsPropType | Available | |
|
||||
| Geolocation | Available | |
|
||||
| I18nManager | Available | Includes additional support for runtime switch to RTL. |
|
||||
| ImageEditor | Not started | No equivalent web APIs. |
|
||||
| ImageStore | Not started | No equivalent web APIs. |
|
||||
| InteractionManager | Available (partial) | |
|
||||
| Keyboard | Mock | |
|
||||
| LayoutAnimation | Available (partial) | Missing transform to web animation. |
|
||||
| Linking | Available | |
|
||||
| NativeEventEmitter | Available | |
|
||||
| NativeMethodsMixin | Available | |
|
||||
| NativeModules | Available (partial) | Mocked. Missing ability to load native modules. |
|
||||
| NetInfo | Available (partial) | Missing functionality to detect extensive connections. |
|
||||
| PanResponder | Available | |
|
||||
| PixelRatio | Available | |
|
||||
| Platform | Available | |
|
||||
| PointPropType | Available | |
|
||||
| Settings | Not started | |
|
||||
| Share | Available | Only available over HTTPS. Read about the [Web Share API](https://wicg.github.io/web-share/). |
|
||||
| StyleSheet | Available | |
|
||||
| TextPropTypes | Available | |
|
||||
| UIManager | Available | |
|
||||
| Vibration | Available | |
|
||||
| ViewPropTypes | Available | |
|
||||
| Name | Status | Notes |
|
||||
| :----------------------- | :----- | :---- |
|
||||
| AccessibilityInfo | (✓) | Mock. No equivalent web APIs. |
|
||||
| Alert | ✘ | Not started ([#1026](https://github.com/necolas/react-native-web/issues/1026)). |
|
||||
| Animated | ✓ | Missing `useNativeDriver` support. |
|
||||
| AppRegistry | ✓ | Includes additional support for server rendering with `getApplication`. |
|
||||
| AppState | ✓ | |
|
||||
| AsyncStorage | ✓ | |
|
||||
| BackHandler | (✓) | Mock. No equivalent web APIs. |
|
||||
| CameraRoll | ✘ | No equivalent web APIs. |
|
||||
| Clipboard | ✓ | |
|
||||
| ColorPropType | ✓ | |
|
||||
| DeviceInfo | (✓) | Limited information. |
|
||||
| Dimensions | ✓ | |
|
||||
| Easing | ✓ | |
|
||||
| EdgeInsetsPropType | ✓ | |
|
||||
| Geolocation | ✓ | |
|
||||
| I18nManager | ✓ | Includes additional support for runtime switch to RTL. |
|
||||
| ImageEditor | ✘ | No equivalent web APIs. |
|
||||
| ImageStore | ✘ | No equivalent web APIs. |
|
||||
| InteractionManager | (✓) | |
|
||||
| Keyboard | (✓) | Mock. |
|
||||
| LayoutAnimation | (✓) | Missing translation to web animations. |
|
||||
| Linking | ✓ | |
|
||||
| NativeEventEmitter | ✓ | |
|
||||
| NativeMethodsMixin | ✓ | |
|
||||
| NativeModules | (✓) | Mocked. Missing ability to load native modules. |
|
||||
| NetInfo | ✓ | Missing functionality to detect expensive connections as there are no equivalent web APIs. |
|
||||
| PanResponder | ✓ | |
|
||||
| PixelRatio | ✓ | |
|
||||
| Platform | ✓ | |
|
||||
| PointPropType | ✓ | |
|
||||
| Settings | ✘ | No equivalent web APIs. |
|
||||
| Share | ✓ | Only available over HTTPS. Read about the [Web Share API](https://wicg.github.io/web-share/). |
|
||||
| StyleSheet | ✓ | |
|
||||
| TextPropTypes | ✓ | |
|
||||
| UIManager | ✓ | |
|
||||
| Vibration | ✓ | |
|
||||
| ViewPropTypes | ✓ | |
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
42
docs/guides/client-side-rendering.md
Normal file
42
docs/guides/client-side-rendering.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# Client-side rendering
|
||||
|
||||
Render apps using `AppRegistry`:
|
||||
|
||||
```js
|
||||
// index.web.js
|
||||
|
||||
import App from './src/App';
|
||||
import React from 'react';
|
||||
import { AppRegistry } from 'react-native';
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App);
|
||||
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: document.getElementById('react-app')
|
||||
});
|
||||
```
|
||||
|
||||
Or render individual components:
|
||||
|
||||
```js
|
||||
import AppHeader from './src/AppHeader';
|
||||
import React from 'react';
|
||||
import { render } from 'react-native';
|
||||
|
||||
render(<AppHeader />, document.getElementById('react-app-header'))
|
||||
```
|
||||
|
||||
(Components will also be rendered within a tree produced by calling
|
||||
`ReactDOM.render` (i.e., an existing web app), but
|
||||
otherwise it is not recommended.)
|
||||
|
||||
You might need to adjust the styles of the HTML document's root elements for
|
||||
your app to fill the viewport.
|
||||
|
||||
```html
|
||||
<html style="height:100%">
|
||||
<body style="height:100%">
|
||||
<div id="react-root" style="display:flex;height:100%"></div>
|
||||
```
|
||||
116
docs/guides/getting-started.md
Normal file
116
docs/guides/getting-started.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Getting started
|
||||
|
||||
This guide will help you render components and applications with React Native
|
||||
for Web.
|
||||
|
||||
Your application may need to polyfill `Promise`, `Object.assign`, `Array.from`,
|
||||
and [`ResizeObserver`](https://github.com/que-etc/resize-observer-polyfill) as
|
||||
necessary for your desired browser support.
|
||||
|
||||
If you're not familiar with setting up a new React web project, please follow
|
||||
the recommendations in the [React documentation](https://reactjs.org/).
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
yarn add react react-dom react-native-web
|
||||
```
|
||||
|
||||
And if you need to use `ART`:
|
||||
|
||||
```
|
||||
yarn add react-art
|
||||
```
|
||||
|
||||
## Starter kits
|
||||
|
||||
Web: [create-react-app](https://github.com/facebookincubator/create-react-app)
|
||||
includes built-in support for aliasing `react-native-web` to `react-native`.
|
||||
|
||||
```
|
||||
create-react-app my-app
|
||||
```
|
||||
|
||||
Multi-platform: [create-react-native-app](https://github.com/react-community/create-react-native-app)
|
||||
includes experimental support for Web.
|
||||
|
||||
```
|
||||
create-react-native-app my-app --with-web-support
|
||||
```
|
||||
|
||||
## Configuring a module bundler
|
||||
|
||||
If you have a custom setup, you may choose to configure your module bundler to
|
||||
alias the package to `react-native`.
|
||||
|
||||
For example, modify your [webpack](https://github.com/webpack/webpack)
|
||||
configuration as follows:
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
module.exports = {
|
||||
// ...the rest of your config
|
||||
|
||||
resolve: {
|
||||
alias: {
|
||||
'react-native$': 'react-native-web'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now you can create your components and applications with the React Native API.
|
||||
|
||||
## Configuring Babel
|
||||
|
||||
If you need to do the aliasing with Babel you can use
|
||||
[babel-plugin-module-resolver](https://www.npmjs.com/package/babel-plugin-module-resolver)
|
||||
|
||||
```
|
||||
{
|
||||
"plugins": [
|
||||
["module-resolver", {
|
||||
"alias": {
|
||||
"^react-native$": "react-native-web"
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Configuring Jest
|
||||
|
||||
[Jest](https://facebook.github.io/jest/) can be configured using the provided
|
||||
preset. This will map `react-native` to `react-native-web` and provide
|
||||
appropriate mocks:
|
||||
|
||||
```
|
||||
{
|
||||
"preset": "react-native-web"
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to the Jest documentation for more information.
|
||||
|
||||
## Configuring Flow
|
||||
|
||||
[Flow](https://flow.org) can be configured to understand the aliased module:
|
||||
|
||||
```
|
||||
[options]
|
||||
module.name_mapper='^react-native$' -> 'react-native-web'
|
||||
```
|
||||
|
||||
You may also need to include a custom libdef
|
||||
([example](https://gist.github.com/paularmstrong/f60b40d16fc83e1e8e532d483336f9bb))
|
||||
in your config.
|
||||
|
||||
## Other notes
|
||||
|
||||
### Safari flexbox performance
|
||||
|
||||
Safari prior to version 10.1 can suffer from extremely [poor flexbox
|
||||
performance](https://bugs.webkit.org/show_bug.cgi?id=150445). The recommended
|
||||
way to work around this issue (as used on mobile.twitter.com) is to set
|
||||
`display:block` on Views in your element hierarchy that you know don't need
|
||||
flexbox layout.
|
||||
154
docs/guides/multi-platform-apps.md
Normal file
154
docs/guides/multi-platform-apps.md
Normal file
@@ -0,0 +1,154 @@
|
||||
# Multi-platform applications
|
||||
|
||||
## Web-specific code
|
||||
|
||||
Minor platform differences can use the `Platform` module.
|
||||
|
||||
```js
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
height: (Platform.OS === 'web') ? 200 : 100,
|
||||
});
|
||||
```
|
||||
|
||||
More significant platform differences should use platform-specific files (see
|
||||
the webpack configuration below for resolving `*.web.js` files):
|
||||
|
||||
For example, with the following files in your project:
|
||||
|
||||
```
|
||||
MyComponent.android.js
|
||||
MyComponent.ios.js
|
||||
MyComponent.web.js
|
||||
```
|
||||
|
||||
And the following import:
|
||||
|
||||
```js
|
||||
import MyComponent from './MyComponent';
|
||||
```
|
||||
|
||||
React Native will automatically import the correct variant for each specific
|
||||
target platform.
|
||||
|
||||
## Web packaging for existing React Native apps
|
||||
|
||||
What follows is merely an _example_ of one basic way to package a web app using
|
||||
[Webpack](https://webpack.js.org) and [Babel](https://babeljs.io/). (You can
|
||||
also the React Native bundler, [Metro](https://github.com/facebook/metro), to
|
||||
build web apps.)
|
||||
|
||||
Packaging web apps is subtly different to packaging React Native apps and is
|
||||
complicated by the need to tree-shake and code-split non-trivial apps.
|
||||
|
||||
Install webpack-related dependencies, for example:
|
||||
|
||||
```
|
||||
yarn add --dev babel-loader url-loader webpack webpack-cli webpack-dev-server
|
||||
```
|
||||
|
||||
React Native's Babel preset rewrites ES modules to CommonJS modules, preventing
|
||||
bundlers from automatically performing "tree-shaking" to remove unused modules
|
||||
from your web app build. To help with this, you can install the following Babel
|
||||
plugin:
|
||||
|
||||
```
|
||||
yarn install --dev babel-plugin-react-native-web
|
||||
```
|
||||
|
||||
Create a `web/webpack.config.js` file:
|
||||
|
||||
```js
|
||||
// web/webpack.config.js
|
||||
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const appDirectory = path.resolve(__dirname, '../');
|
||||
|
||||
// This is needed for webpack to compile JavaScript.
|
||||
// Many OSS React Native packages are not compiled to ES5 before being
|
||||
// published. If you depend on uncompiled packages they may cause webpack build
|
||||
// errors. To fix this webpack can be configured to compile to the necessary
|
||||
// `node_module`.
|
||||
const babelLoaderConfiguration = {
|
||||
test: /\.js$/,
|
||||
// Add every directory that needs to be compiled by Babel during the build.
|
||||
include: [
|
||||
path.resolve(appDirectory, 'index.web.js'),
|
||||
path.resolve(appDirectory, 'src'),
|
||||
path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
|
||||
],
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
// The 'react-native' preset is recommended to match React Native's packager
|
||||
presets: ['react-native'],
|
||||
// Re-write paths to import only the modules needed by the app
|
||||
plugins: ['react-native-web']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// This is needed for webpack to import static images in JavaScript files.
|
||||
const imageLoaderConfiguration = {
|
||||
test: /\.(gif|jpe?g|png|svg)$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
name: '[name].[ext]'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
entry: [
|
||||
// load any web API polyfills
|
||||
// path.resolve(appDirectory, 'polyfills-web.js'),
|
||||
// your web-specific entry file
|
||||
path.resolve(appDirectory, 'index.web.js')
|
||||
],
|
||||
|
||||
// configures where the build ends up
|
||||
output: {
|
||||
filename: 'bundle.web.js',
|
||||
path: path.resolve(appDirectory, 'dist')
|
||||
},
|
||||
|
||||
// ...the rest of your config
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
babelLoaderConfiguration,
|
||||
imageLoaderConfiguration
|
||||
]
|
||||
},
|
||||
|
||||
resolve: {
|
||||
// This will only alias the exact import "react-native"
|
||||
alias: {
|
||||
'react-native$': 'react-native-web'
|
||||
},
|
||||
// If you're working on a multi-platform React Native app, web-specific
|
||||
// module implementations should be written in files using the extension
|
||||
// `.web.js`.
|
||||
extensions: [ '.web.js', '.js' ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To run in development from the root of your application:
|
||||
|
||||
```
|
||||
./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors
|
||||
```
|
||||
|
||||
To build for production:
|
||||
|
||||
```
|
||||
./node_modules/.bin/webpack -p --config ./web/webpack.config.js
|
||||
```
|
||||
|
||||
Please refer to the Webpack documentation for more information on configuration.
|
||||
33
docs/guides/server-side-rendering.md
Normal file
33
docs/guides/server-side-rendering.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Server-side rendering
|
||||
|
||||
Server-side rendering to HTML is supported using `AppRegistry`:
|
||||
|
||||
```js
|
||||
import App from './src/App';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { AppRegistry } from 'react-native-web';
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App);
|
||||
|
||||
// prerender the app
|
||||
const { element, getStyleElement } = AppRegistry.getApplication('App', { initialProps });
|
||||
// first the element
|
||||
const html = ReactDOMServer.renderToString(element);
|
||||
// then the styles (optionally include a nonce if your CSP policy requires it)
|
||||
const css = ReactDOMServer.renderToStaticMarkup(getStyleElement({ nonce }));
|
||||
|
||||
// example HTML document string
|
||||
const document = `
|
||||
<!DOCTYPE html>
|
||||
<html style="height:100%">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
${css}
|
||||
<body style="height:100%; overflow-y:hidden">
|
||||
<div id="root" style="display:flex; height: 100%">
|
||||
${html}
|
||||
</div>
|
||||
<script nonce="${nonce}" src="${bundlePath}"></script>
|
||||
`
|
||||
```
|
||||
51
docs/guides/web-recipes.md
Normal file
51
docs/guides/web-recipes.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Web recipes
|
||||
|
||||
Examples of how to implement web patterns with React Native.
|
||||
|
||||
#### `html` and `body` styles
|
||||
|
||||
The `html` and `body` elements require certain styles to support full-screen
|
||||
React Native apps, and disable "features" like pull-to-refresh in mobile
|
||||
browsers. Using the `body` as the root scroll view is [not reliably
|
||||
supported](https://github.com/necolas/react-native-web/issues/829).
|
||||
|
||||
[Example code](https://codesandbox.io/s/52x1871vjl).
|
||||
|
||||
#### Hover styles
|
||||
|
||||
Relying on the web's native hover styles can result in several unwanted UX
|
||||
consequences. Hover styles might be displayed during touch interactions and can
|
||||
remain visually "stuck". Furthermore, there's no way to delay or persist hover
|
||||
for accessibility purposes. This recipe shows how to apply hover styles that
|
||||
integrate with the Responder event system (e.g., the `Touchable*` press styles)
|
||||
and display styles *only* when the mouse is active. It can also be used as the
|
||||
basis for programmatic hover delays and rendering of components (e.g., hover
|
||||
cards).
|
||||
|
||||
[Example code](https://codesandbox.io/s/o9q8vy70l5)
|
||||
|
||||
#### Link styles
|
||||
|
||||
Cross-platform link components are straight-forward to create and can be
|
||||
combined with the hover recipe.
|
||||
|
||||
[Example code](https://codesandbox.io/s/53r88k5opx)
|
||||
|
||||
<!--
|
||||
#### Typography
|
||||
|
||||
Rather than relying on inhereted global typography styles, React Native allows
|
||||
you to define components that encapsulate a typographic system. This has the
|
||||
added benefit of enabling content-specific typography adjustments, e.g.,
|
||||
different font sizes or weights for different languages.
|
||||
|
||||
[Example code]()
|
||||
|
||||
#### Responsive font size
|
||||
|
||||
[Example code]()
|
||||
|
||||
#### SVG icons
|
||||
|
||||
[Example code]()
|
||||
-->
|
||||
@@ -1,353 +0,0 @@
|
||||
# Getting started
|
||||
|
||||
This guide will help you render components and applications with React Native
|
||||
for Web.
|
||||
|
||||
Your application may need to polyfill `Promise`, `Object.assign`, `Array.from`,
|
||||
and [`ResizeObserver`](https://github.com/que-etc/resize-observer-polyfill) as
|
||||
necessary for your desired browser support.
|
||||
|
||||
If you're not familiar with setting up a new React web project, please follow
|
||||
the recommendations in the [React documentation](https://reactjs.org/).
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
yarn add react react-dom react-native-web
|
||||
```
|
||||
|
||||
And if you need to use `ART`:
|
||||
|
||||
```
|
||||
yarn add react-art
|
||||
```
|
||||
|
||||
## Starter kits
|
||||
|
||||
Web: [create-react-app](https://github.com/facebookincubator/create-react-app)
|
||||
includes built-in support for aliasing `react-native-web` to `react-native`.
|
||||
|
||||
```
|
||||
create-react-app my-app
|
||||
```
|
||||
|
||||
Multi-platform: [create-react-native-app](https://github.com/react-community/create-react-native-app)
|
||||
includes experimental support for Web.
|
||||
|
||||
```
|
||||
create-react-native-app my-app --with-web-support
|
||||
```
|
||||
|
||||
## Configuring a module bundler
|
||||
|
||||
If you have a custom setup, you may choose to configure your module bundler to
|
||||
alias the package to `react-native`.
|
||||
|
||||
For example, modify your [webpack](https://github.com/webpack/webpack)
|
||||
configuration as follows:
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
module.exports = {
|
||||
// ...the rest of your config
|
||||
|
||||
resolve: {
|
||||
alias: {
|
||||
'react-native$': 'react-native-web'
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Now you can create your components and applications with the React Native API.
|
||||
|
||||
## Configuring babel
|
||||
|
||||
If you need to do the aliasing with Babel you can use
|
||||
[babel-plugin-module-resolver](https://www.npmjs.com/package/babel-plugin-module-resolver)
|
||||
|
||||
```
|
||||
{
|
||||
"plugins": [
|
||||
["module-resolver", {
|
||||
"alias": {
|
||||
"^react-native$": "react-native-web"
|
||||
}
|
||||
}]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Client-side rendering
|
||||
|
||||
Render apps using `AppRegistry`:
|
||||
|
||||
```js
|
||||
// index.web.js
|
||||
|
||||
import App from './src/App';
|
||||
import React from 'react';
|
||||
import { AppRegistry } from 'react-native';
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App);
|
||||
|
||||
AppRegistry.runApplication('App', {
|
||||
initialProps: {},
|
||||
rootTag: document.getElementById('react-app')
|
||||
});
|
||||
```
|
||||
|
||||
Or render individual components:
|
||||
|
||||
```js
|
||||
import AppHeader from './src/AppHeader';
|
||||
import React from 'react';
|
||||
import { render } from 'react-native';
|
||||
|
||||
render(<AppHeader />, document.getElementById('react-app-header'))
|
||||
```
|
||||
|
||||
(Components will also be rendered within a tree produced by calling
|
||||
`ReactDOM.render` (i.e., an existing web app), but
|
||||
otherwise it is not recommended.)
|
||||
|
||||
You might need to adjust the styles of the HTML document's root elements for
|
||||
your app to fill the viewport.
|
||||
|
||||
```html
|
||||
<html style="height:100%">
|
||||
<body style="height:100%">
|
||||
<div id="react-root" style="display:flex;height:100%"></div>
|
||||
```
|
||||
|
||||
## Server-side rendering
|
||||
|
||||
Server-side rendering to HTML is supported using `AppRegistry`:
|
||||
|
||||
```js
|
||||
import App from './src/App';
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { AppRegistry } from 'react-native-web';
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => App);
|
||||
|
||||
// prerender the app
|
||||
const { element, getStyleElement } = AppRegistry.getApplication('App', { initialProps });
|
||||
// first the element
|
||||
const html = ReactDOMServer.renderToString(element);
|
||||
// then the styles (optionally include a nonce if your CSP policy requires it)
|
||||
const css = ReactDOMServer.renderToStaticMarkup(getStyleElement({ nonce }));
|
||||
|
||||
// example HTML document string
|
||||
const document = `
|
||||
<!DOCTYPE html>
|
||||
<html style="height:100%">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
${css}
|
||||
<body style="height:100%; overflow-y:hidden">
|
||||
<div id="root" style="display:flex; height: 100%">
|
||||
${html}
|
||||
</div>
|
||||
<script nonce="${nonce}" src="${bundlePath}"></script>
|
||||
`
|
||||
```
|
||||
|
||||
## Testing with Jest
|
||||
|
||||
[Jest](https://facebook.github.io/jest/) can be configured using the provided
|
||||
preset. This will map `react-native` to `react-native-web` and provide
|
||||
appropriate mocks:
|
||||
|
||||
```
|
||||
{
|
||||
"preset": "react-native-web"
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to the Jest documentation for more information.
|
||||
|
||||
## Using Flow
|
||||
|
||||
[Flow](https://flow.org) can be configured to understand the aliased module:
|
||||
|
||||
```
|
||||
[options]
|
||||
module.name_mapper='^react-native$' -> 'react-native-web'
|
||||
```
|
||||
|
||||
You may also need to include a custom libdef
|
||||
([example](https://gist.github.com/paularmstrong/f60b40d16fc83e1e8e532d483336f9bb))
|
||||
in your config.
|
||||
|
||||
## Multi-platform applications
|
||||
|
||||
### Web-specific code
|
||||
|
||||
Minor platform differences can use the `Platform` module.
|
||||
|
||||
```js
|
||||
import { Platform } from 'react-native';
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
height: (Platform.OS === 'web') ? 200 : 100,
|
||||
});
|
||||
```
|
||||
|
||||
More significant platform differences should use platform-specific files (see
|
||||
the webpack configuration below for resolving `*.web.js` files):
|
||||
|
||||
For example, with the following files in your project:
|
||||
|
||||
```
|
||||
MyComponent.android.js
|
||||
MyComponent.ios.js
|
||||
MyComponent.web.js
|
||||
```
|
||||
|
||||
And the following import:
|
||||
|
||||
```js
|
||||
import MyComponent from './MyComponent';
|
||||
```
|
||||
|
||||
React Native will automatically import the correct variant for each specific
|
||||
target platform.
|
||||
|
||||
## Web packaging for existing React Native apps
|
||||
|
||||
What follows is merely an _example_ of one basic way to package a web app using
|
||||
[Webpack](https://webpack.js.org) and [Babel](https://babeljs.io/). (You can
|
||||
also the React Native bundler, [Metro](https://github.com/facebook/metro), to
|
||||
build web apps.)
|
||||
|
||||
Packaging web apps is subtly different to packaging React Native apps and is
|
||||
complicated by the need to tree-shake and code-split non-trivial apps.
|
||||
|
||||
Install webpack-related dependencies, for example:
|
||||
|
||||
```
|
||||
yarn add --dev babel-loader url-loader webpack webpack-cli webpack-dev-server
|
||||
```
|
||||
|
||||
React Native's Babel preset rewrites ES modules to CommonJS modules, preventing
|
||||
bundlers from automatically performing "tree-shaking" to remove unused modules
|
||||
from your web app build. To help with this, you can install the following Babel
|
||||
plugin:
|
||||
|
||||
```
|
||||
yarn install --dev babel-plugin-react-native-web
|
||||
```
|
||||
|
||||
Create a `web/webpack.config.js` file:
|
||||
|
||||
```js
|
||||
// web/webpack.config.js
|
||||
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const appDirectory = path.resolve(__dirname, '../');
|
||||
|
||||
// This is needed for webpack to compile JavaScript.
|
||||
// Many OSS React Native packages are not compiled to ES5 before being
|
||||
// published. If you depend on uncompiled packages they may cause webpack build
|
||||
// errors. To fix this webpack can be configured to compile to the necessary
|
||||
// `node_module`.
|
||||
const babelLoaderConfiguration = {
|
||||
test: /\.js$/,
|
||||
// Add every directory that needs to be compiled by Babel during the build.
|
||||
include: [
|
||||
path.resolve(appDirectory, 'index.web.js'),
|
||||
path.resolve(appDirectory, 'src'),
|
||||
path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
|
||||
],
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
// The 'react-native' preset is recommended to match React Native's packager
|
||||
presets: ['react-native'],
|
||||
// Re-write paths to import only the modules needed by the app
|
||||
plugins: ['react-native-web']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// This is needed for webpack to import static images in JavaScript files.
|
||||
const imageLoaderConfiguration = {
|
||||
test: /\.(gif|jpe?g|png|svg)$/,
|
||||
use: {
|
||||
loader: 'url-loader',
|
||||
options: {
|
||||
name: '[name].[ext]'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
entry: [
|
||||
// load any web API polyfills
|
||||
// path.resolve(appDirectory, 'polyfills-web.js'),
|
||||
// your web-specific entry file
|
||||
path.resolve(appDirectory, 'index.web.js')
|
||||
],
|
||||
|
||||
// configures where the build ends up
|
||||
output: {
|
||||
filename: 'bundle.web.js',
|
||||
path: path.resolve(appDirectory, 'dist')
|
||||
},
|
||||
|
||||
// ...the rest of your config
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
babelLoaderConfiguration,
|
||||
imageLoaderConfiguration
|
||||
]
|
||||
},
|
||||
|
||||
resolve: {
|
||||
// This will only alias the exact import "react-native"
|
||||
alias: {
|
||||
'react-native$': 'react-native-web'
|
||||
},
|
||||
// If you're working on a multi-platform React Native app, web-specific
|
||||
// module implementations should be written in files using the extension
|
||||
// `.web.js`.
|
||||
extensions: [ '.web.js', '.js' ]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
To run in development from the root of your application:
|
||||
|
||||
```
|
||||
./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors
|
||||
```
|
||||
|
||||
To build for production:
|
||||
|
||||
```
|
||||
./node_modules/.bin/webpack -p --config ./web/webpack.config.js
|
||||
```
|
||||
|
||||
Please refer to the Webpack documentation for more information on configuration.
|
||||
|
||||
## Other notes
|
||||
|
||||
### Safari flexbox performance
|
||||
|
||||
Safari prior to version 10.1 can suffer from extremely [poor flexbox
|
||||
performance](https://bugs.webkit.org/show_bug.cgi?id=150445). The recommended
|
||||
way to work around this issue (as used on mobile.twitter.com) is to set
|
||||
`display:block` on Views in your element hierarchy that you know don't need
|
||||
flexbox layout.
|
||||
|
||||
### Platform-specific component props
|
||||
|
||||
There are properties that do not work across all platforms. All web-specific
|
||||
props are annotated with `(web)` in the documentation.
|
||||
Reference in New Issue
Block a user