diff --git a/README.md b/README.md index 4e3ba96b..f797773b 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ To install in your app: npm install --save react@15.4 react-dom@15.4 react-native-web ``` -Read the [Client and Server rendering](docs/guides/rendering.md) guide. +Read the [Getting Started](docs/guides/getting-started.md) guide. Alternatively, you can quickly setup a local project using [create-react-app](https://github.com/facebookincubator/create-react-app) @@ -41,12 +41,11 @@ using [create-react-app](https://github.com/facebookincubator/create-react-app) Guides: +* [Getting started](docs/guides/getting-started.md) * [Accessibility](docs/guides/accessibility.md) -* [Client and server rendering](docs/guides/rendering.md) * [Direct manipulation](docs/guides/direct-manipulation.md) * [Internationalization](docs/guides/internationalization.md) * [Known issues](docs/guides/known-issues.md) -* [React Native](docs/guides/react-native.md) * [Style](docs/guides/style.md) Exported modules: @@ -143,8 +142,8 @@ AppRegistry.runApplication('MyApp', { rootTag: document.getElementById('react-ro * [react-native-web-starter](https://github.com/grabcode/react-native-web-starter) * [react-native-web-player](https://github.com/dabbott/react-native-web-player) +* [reactxp](https://github.com/microsoft/reactxp) * [react-web](https://github.com/taobaofed/react-web) -* [react-native-for-web](https://github.com/KodersLab/react-native-for-web) * [rhinos-app](https://github.com/rhinos-app/rhinos-app-dev) ## License diff --git a/docs/guides/getting-started.md b/docs/guides/getting-started.md new file mode 100644 index 00000000..d7af0225 --- /dev/null +++ b/docs/guides/getting-started.md @@ -0,0 +1,184 @@ +# Getting started + +## Webpack + +Working with React Native for Web is easiest with webpack. + +### alias + +Alias `react-native-web` to `react-native` in order to load the web +implementation when importing `react-native`. + +```js +// webpack.config.js + +module.exports = { + // ...rest of config + resolve: { + alias: { + 'react-native': 'react-native-web' + } + } +} +``` + +### loaders + + +In order to require image assets (e.g. `require('assets/myimage.png')`), add +the `url-loader` to the webpack config: + +To support modern ES features, use the `babel-loader`. Many OSS React Native +packages are not compiled to ES5 before being published. This can result in +webpack build errors. To avoid this issue you should configure webpack (or your +bundler of choice) to run `babel-preset-react-native` over the necessary +`node_module`. + + +```js +// webpack.config.js + +module.exports = { + // ... + module: { + rules: [ + { + test: /\.js$/, + include: [ + // local app code + path.resolve(__dirname, 'src'), + // dependency that wasn't transpiled to ES5 + path.resolve(__dirname, 'node_modules/react-native-something') + ], + use: { + loader: 'babel-loader', + query: { cacheDirectory: true } + } + }, + { + test: /\.(gif|jpe?g|png|svg)$/, + use: { + loader: 'url-loader', + query: { name: '[name].[ext]' } + } + } + ] + } +}; +``` + +Please refer to the Webpack documentation for more information. + +## Jest + +Alias `react-native-web` to `react-native` in your Jest config. + +``` +"jest": { + "moduleNameMapper": { + "react-native": "/node_modules/react-native-web" + } +} +``` + +Please refer to the Jest documentation for more information. + +## Web-specific code + +Minor platform differences can use the `Platform` module. + +```js +import { AppRegistry, Platform } from 'react-native' + +AppRegistry.registerComponent('MyApp', () => MyApp) + +if (Platform.OS === 'web') { + AppRegistry.runApplication('MyApp', { + rootTag: document.getElementById('react-root') + }); +} +``` + +More substantial Web-specific implementation code should be written in files +with the extension `.web.js`. Webpack@1 will automatically resolve these files. +Webpack@2 requires additional configuration. + +```js +// webpack.config.js + +module.exports = { + // ... + resolve: { + extensions: [ '.web.js', '.js' ] + } +}; +``` + +## Build optimizations + +Production builds can benefit from dead-code elimination by defining the +following variables: + +```js +// webpack.config.js + +module.exports = { + // ... + plugins: [ + new webpack.DefinePlugin({ + 'process.env.NODE_ENV': JSON.stringify('production') + }) + } +} +``` + +## Client-side rendering + +Rendering without using the `AppRegistry`: + +```js +import React from 'react' +import ReactNative from 'react-native' + +// component that renders the app +const AppHeaderContainer = (props) => { /* ... */ } + +ReactNative.render(, document.getElementById('react-app-header')) +``` + +Rendering using the `AppRegistry`: + +```js +import React from 'react' +import ReactNative, { AppRegistry } from 'react-native' + +// component that renders the app +const AppContainer = (props) => { /* ... */ } + +// register the app +AppRegistry.registerComponent('App', () => AppContainer) + +AppRegistry.runApplication('App', { + initialProps: {}, + rootTag: document.getElementById('react-app') +}) +``` + +## Server-side rendering + +Rendering using the `AppRegistry`: + +```js +import ReactDOMServer from 'react-dom/server' +import ReactNative, { AppRegistry } from 'react-native' + +// component that renders the app +const AppContainer = (props) => { /* ... */ } + +// register the app +AppRegistry.registerComponent('App', () => AppContainer) + +// prerender the app +const { element, stylesheet } = AppRegistry.getApplication('App', { initialProps }); +const initialHTML = ReactDOMServer.renderToString(element); +``` diff --git a/docs/guides/react-native.md b/docs/guides/react-native.md deleted file mode 100644 index 3d14a0e0..00000000 --- a/docs/guides/react-native.md +++ /dev/null @@ -1,119 +0,0 @@ -# React Native - -Use a module loader that supports package aliases (e.g., webpack), and alias -`react-native` to `react-native-web`. - -```js -// webpack.config.js - -module.exports = { - // ... - resolve: { - alias: { - 'react-native': 'react-native-web' - } - } -} -``` - -## Image assets - -In order to require image assets (e.g. `require('assets/myimage.png')`), add -the `url-loader` to the webpack config: - -```js -// webpack.config.js - -module.exports = { - // ... - module: { - loaders: [ - { - test: /\.(gif|jpe?g|png|svg)$/, - loader: 'url-loader', - query: { name: '[name].[hash:16].[ext]' } - } - ] - } -}; -``` - -## Dependencies - -Many OSS React Native packages are not compiled to ES5 before being published. -This can result in webpack build errors. To avoid this issue you should -configure webpack (or your bundler of choice) to run -`babel-preset-react-native` over the necessary `node_module`. For example: - -```js -// webpack.config.js - -module.exports = { - // ... - module: { - loaders: [ - { - // transpile to ES5 - test: /\.jsx?$/, - include: [ - path.resolve(__dirname, 'src'), - path.resolve(__dirname, 'node_modules/react-native-something') - ], - loader: 'babel-loader', - query: { cacheDirectory: true } - } - ] - } -}; -``` - -Please refer to the webpack documentation for more information. - -## Web-specific code - -Minor platform differences can use the `Platform` module. - -```js -import { AppRegistry, Platform } from 'react-native' - -AppRegistry.registerComponent('MyApp', () => MyApp) - -if (Platform.OS === 'web') { - AppRegistry.runApplication('MyApp', { - rootTag: document.getElementById('react-root') - }); -} -``` - -More substantial Web-specific implementation code should be written in files -with the extension `.web.js`. Webpack@1 will automatically resolve these files. -Webpack@2 requires additional configuration. - -```js -// webpack.config.js - -module.exports = { - // ... - resolve: { - extensions: [ '.web.js', '.js' ] - } -}; -``` - -## Optimizations - -Production builds can benefit from dead-code elimination by defining the -following variables: - -```js -// webpack.config.js - -module.exports = { - // ... - plugins: [ - new webpack.DefinePlugin({ - 'process.env.NODE_ENV': JSON.stringify('production') - }) - } -} -``` diff --git a/docs/guides/rendering.md b/docs/guides/rendering.md deleted file mode 100644 index ddb1adfa..00000000 --- a/docs/guides/rendering.md +++ /dev/null @@ -1,89 +0,0 @@ -# Client and Server rendering - -It's recommended that you use a module loader that supports package aliases -(e.g., webpack), and alias `react-native` to `react-native-web`. - -```js -// webpack.config.js - -module.exports = { - // ...other configuration - resolve: { - alias: { - 'react-native': 'react-native-web' - } - } -} -``` - -The `react-native-web` package also includes a `core` module that exports a -subset of modules: `ReactNative`, `I18nManager`, `Platform`, `StyleSheet`, -`Image`, `Text`, `TextInput`, `Touchable`, and `View`. - -```js -// webpack.config.js - -module.exports = { - // ...other configuration - resolve: { - alias: { - 'react-native': 'react-native-web/core' - } - } -} -``` - -## Client-side rendering - -Rendering without using the `AppRegistry`: - -```js -import React from 'react' -import ReactNative from 'react-native' - -// component that renders the app -const AppHeaderContainer = (props) => { /* ... */ } - -ReactNative.render(, document.getElementById('react-app-header')) -``` - -Rendering using the `AppRegistry`: - -```js -import React from 'react' -import ReactNative, { AppRegistry } from 'react-native' - -// component that renders the app -const AppContainer = (props) => { /* ... */ } - -// register the app -AppRegistry.registerComponent('App', () => AppContainer) - -AppRegistry.runApplication('App', { - initialProps: {}, - rootTag: document.getElementById('react-app') -}) -``` - -Setting `process.env.__REACT_NATIVE_DEBUG_ENABLED__` to `true` will expose some -debugging logs. This can help track down when you're rendering without the -performance benefit of cached styles. - -## Server-side rendering - -Rendering using the `AppRegistry`: - -```js -import ReactDOMServer from 'react-dom/server' -import ReactNative, { AppRegistry } from 'react-native' - -// component that renders the app -const AppContainer = (props) => { /* ... */ } - -// register the app -AppRegistry.registerComponent('App', () => AppContainer) - -// prerender the app -const { element, stylesheet } = AppRegistry.getApplication('App', { initialProps }); -const initialHTML = ReactDOMServer.renderToString(element); -```