mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-08-15 18:45:06 +00:00
Documentation updates
This commit is contained in:
@@ -29,8 +29,9 @@ Browser support: Chrome, Firefox, Edge, Safari 7+, IE 10+.
|
||||
## Quick start
|
||||
|
||||
The easiest way to get started with React Native for Web is to use this
|
||||
[ready-to-go project on Glitch](https://glitch.com/edit/#!/react-native).
|
||||
You don’t need to install anything to try it out.
|
||||
[CodeSandbox](https://codesandbox.io/s/q4qymyp2l6) template (or
|
||||
[Glitch](https://glitch.com/edit/#!/react-native)). You don’t need to install
|
||||
anything to try it out.
|
||||
|
||||
## Documentation
|
||||
|
||||
@@ -42,21 +43,6 @@ design details, and for 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).
|
||||
|
||||
### Installation
|
||||
|
||||
Install using `yarn` or `npm`:
|
||||
|
||||
```
|
||||
yarn add react react-dom react-native-web
|
||||
yarn add --dev babel-plugin-react-native-web
|
||||
```
|
||||
|
||||
And if you need to use `ART`:
|
||||
|
||||
```
|
||||
yarn add react-art
|
||||
```
|
||||
|
||||
### Guides
|
||||
|
||||
* [Getting started](https://github.com/necolas/react-native-web/blob/master/website/guides/getting-started.md)
|
||||
@@ -109,8 +95,8 @@ Examples of using React Native for Web with other web tools:
|
||||
* [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/0.5.1/website/storybook/.storybook)
|
||||
* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/v6.2.6/examples/react-native)
|
||||
* [Storybook](https://github.com/necolas/react-native-web/tree/master/website/storybook/.storybook)
|
||||
* [Styleguidist](https://github.com/styleguidist/react-styleguidist/tree/master/examples/react-native)
|
||||
|
||||
## Contributing
|
||||
|
||||
|
||||
@@ -39,29 +39,39 @@ using `aria-label`.
|
||||
|
||||
In some cases, we also want to alert the end user of the type of selected
|
||||
component (i.e., that it is a “button”). To provide more context to screen
|
||||
readers, you should specify the `accessibilityRole` property. (Note that React
|
||||
Native for Web also provides a compatibility mapping of equivalent
|
||||
readers on the web, you should use the `accessibilityRole` property. (Note that
|
||||
React Native for Web also provides a compatibility mapping of equivalent
|
||||
`accessibilityTraits` and `accessibilityComponentType` values to
|
||||
`accessibilityRole`).
|
||||
|
||||
The `accessibilityRole` prop is used to infer an [analogous HTML
|
||||
element][html-aria-url] and ARIA `role`, where possible. In most cases, both
|
||||
the element and ARIA `role` are rendered. While this may contradict some ARIA
|
||||
recommendations, it also helps avoid certain HTML5 conformance errors and
|
||||
accessibility anti-patterns (e.g., giving a `heading` role to a `button`
|
||||
element) and browser bugs.
|
||||
recommendations, it also helps avoid certain browser bugs, HTML5 conformance
|
||||
errors, and accessibility anti-patterns (e.g., giving a `heading` role to a
|
||||
`button` element).
|
||||
|
||||
For example:
|
||||
Straight-forward examples:
|
||||
|
||||
* `<View accessibilityRole='article' />` => `<article role='article' />`.
|
||||
* `<View accessibilityRole='banner' />` => `<header role='banner' />`.
|
||||
* `<View accessibilityRole='button' />` => `<div role='button' tabIndex='0' />`.
|
||||
* `<Text accessibilityRole='label' />` => `<label />`.
|
||||
* `<Text accessibilityRole='link' href='/' />` => `<a role='link' href='/' />`.
|
||||
* `<View accessibilityRole='main' />` => `<main role='main' />`.
|
||||
* `<View accessibilityRole="article" />` => `<article role="article" />`.
|
||||
* `<View accessibilityRole="banner" />` => `<header role="banner" />`.
|
||||
* `<Text accessibilityRole="label" />` => `<label />`.
|
||||
* `<Text accessibilityRole="link" />` => `<a role="link" />`.
|
||||
* `<View accessibilityRole="main" />` => `<main role="main" />`.
|
||||
|
||||
In the example below, the `TouchableHighlight` is announced by screen
|
||||
readers as a button.
|
||||
The `heading` role can be combined with `aria-level`:
|
||||
|
||||
* `<Text accessibilityRole="heading" />` => `<h1 />`.
|
||||
* `<Text accessibilityRole="heading" aria-level="3" />` => `<h3 />`.
|
||||
|
||||
The `button` role renders an accessible button but is not implemented using the
|
||||
native `button` element due to some browsers limiting the use of flexbox layout on
|
||||
its children.
|
||||
|
||||
* `<View accessibilityRole="button" />` => `<div role="button" tabIndex="0" />`.
|
||||
|
||||
In the example below, the `TouchableHighlight` is announced by screen readers
|
||||
as a button and it responds to touch, mouse, and keyboard interactions.
|
||||
|
||||
```js
|
||||
<TouchableHighlight accessibilityRole="button" onPress={this._handlePress}>
|
||||
@@ -71,16 +81,13 @@ readers as a button.
|
||||
</TouchableHighlight>
|
||||
```
|
||||
|
||||
Note: The `button` role is not implemented using the native `button` element
|
||||
due to browsers limiting the use of flexbox layout on its children.
|
||||
|
||||
Note: Avoid changing `accessibilityRole` values over time or after user
|
||||
actions. Generally, accessibility APIs do not provide a means of notifying
|
||||
assistive technologies of a `role` value change.
|
||||
|
||||
### accessibilityLiveRegion
|
||||
|
||||
When components dynamically change we may need to inform the user. The
|
||||
When components dynamically change we may need to inform the user. The
|
||||
`accessibilityLiveRegion` property serves this purpose and can be set to
|
||||
`none`, `polite` and `assertive`. On web, `accessibilityLiveRegion` is
|
||||
implemented using `aria-live`.
|
||||
|
||||
@@ -1,28 +1,65 @@
|
||||
# Getting started
|
||||
|
||||
This guide will help you to use and test React Native for Web once it has been installed.
|
||||
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.
|
||||
|
||||
## Adding to a new web app
|
||||
|
||||
The easiest way to create a new web app with React Native for Web is to rely on
|
||||
Facebook's React web starter kit –
|
||||
[create-react-app](https://github.com/facebookincubator/create-react-app). All
|
||||
that is needed after initializing a web app with CRA is to install
|
||||
`react-native-web`.
|
||||
|
||||
If you are unfamiliar with setting up a new React web project, please follow
|
||||
If you're not familiar with setting up a new React web project, please follow
|
||||
the recommendations in the [React documentation](https://reactjs.org/).
|
||||
|
||||
## Adding to an existing web app
|
||||
## Install
|
||||
|
||||
Existing web apps need to alias `react-native` to `react-native-web` and
|
||||
exclude any modules not required by the app. You can do this by adding
|
||||
[`babel-plugin-react-native-web`](https://www.npmjs.com/package/babel-plugin-react-native-web)
|
||||
to the plugins in your Babel configuration.
|
||||
```
|
||||
yarn install 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
|
||||
```
|
||||
|
||||
## Configure 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:
|
||||
|
||||
```
|
||||
// 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.
|
||||
|
||||
## Client-side rendering
|
||||
|
||||
@@ -44,7 +81,7 @@ AppRegistry.runApplication('App', {
|
||||
});
|
||||
```
|
||||
|
||||
Render components within existing apps:
|
||||
Or render individual components:
|
||||
|
||||
```js
|
||||
import AppHeader from './src/AppHeader';
|
||||
@@ -54,9 +91,18 @@ import { render } from 'react-native';
|
||||
render(<AppHeader />, document.getElementById('react-app-header'))
|
||||
```
|
||||
|
||||
Components will also be rendered within a tree produced by calling
|
||||
(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.
|
||||
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
|
||||
|
||||
@@ -64,31 +110,65 @@ 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'
|
||||
import ReactDOMServer from 'react-dom/server';
|
||||
import { AppRegistry } from 'react-native-web';
|
||||
|
||||
// register the app
|
||||
AppRegistry.registerComponent('App', () => 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
|
||||
const css = ReactDOMServer.renderToStaticMarkup(getStyleElement());
|
||||
// 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>
|
||||
<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>
|
||||
`
|
||||
```
|
||||
|
||||
## Web-specific code
|
||||
## Testing with Jest
|
||||
|
||||
[Jest](https://facebook.github.io/jest/) can be configured to alias
|
||||
`react-native-web` and improve snapshots:
|
||||
|
||||
```
|
||||
{
|
||||
"moduleNameMapper": {
|
||||
"react-native": "<rootDir>/node_modules/react-native-web"
|
||||
},
|
||||
"snapshotSerializers": [
|
||||
"enzyme-to-json/serializer",
|
||||
"react-native-web/jest/serializer"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
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'
|
||||
```
|
||||
|
||||
## Multi-platform applications
|
||||
|
||||
### Web-specific code
|
||||
|
||||
Minor platform differences can use the `Platform` module.
|
||||
|
||||
@@ -120,38 +200,15 @@ import MyComponent from './MyComponent';
|
||||
React Native will automatically import the correct variant for each specific
|
||||
target platform.
|
||||
|
||||
## Testing with Jest
|
||||
|
||||
[Jest](https://facebook.github.io/jest/) can be configured to improve snapshots
|
||||
of `react-native-web` components.
|
||||
|
||||
```
|
||||
{
|
||||
"snapshotSerializers": [ "enzyme-to-json/serializer", "react-native-web/jest/serializer" ]
|
||||
}
|
||||
```
|
||||
|
||||
Jest also needs to map `react-native` to `react-native-web` (unless you are
|
||||
using the Babel plugin).
|
||||
|
||||
```
|
||||
{
|
||||
"moduleNameMapper": {
|
||||
"react-native": "<rootDir>/node_modules/react-native-web"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Please refer to the Jest documentation for more information.
|
||||
|
||||
## Web packaging for existing React Native apps
|
||||
|
||||
The web packaging landscape is diverse and fractured. Packaging web apps is
|
||||
subtly different to packaging React Native apps and is also complicated by the
|
||||
need to code-split non-trivial 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.)
|
||||
|
||||
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/).
|
||||
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:
|
||||
|
||||
@@ -159,6 +216,14 @@ 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
|
||||
@@ -186,12 +251,10 @@ const babelLoaderConfiguration = {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
cacheDirectory: true,
|
||||
// Babel configuration (or use .babelrc)
|
||||
// This aliases 'react-native' to 'react-native-web' and includes only
|
||||
// the modules needed by the app.
|
||||
plugins: ['react-native-web'],
|
||||
// The 'react-native' preset is recommended to match React Native's packager
|
||||
presets: ['react-native']
|
||||
presets: ['react-native'],
|
||||
// Re-write paths to import only the modules needed by the app
|
||||
plugins: ['react-native-web']
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -226,17 +289,10 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
|
||||
plugins: [
|
||||
// `process.env.NODE_ENV === 'production'` must be `true` for production
|
||||
// builds to eliminate development checks and reduce build size. You may
|
||||
// wish to include additional optimizations.
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development'),
|
||||
__DEV__: process.env.NODE_ENV !== 'production' || true
|
||||
})
|
||||
],
|
||||
|
||||
resolve: {
|
||||
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`.
|
||||
|
||||
Reference in New Issue
Block a user