Run react native apps in your browser!
This project uses react-native-web to create an environment for learning and experimenting with React Native.
The web player is implemented as an iframe for easy, performant inclusion in any webpage. Transpilation is done in a web worker so the main thread isn't blocked as the page loads.
The web player may be included in your site either as a React component or directly as an iframe.
If you're using React:
npm install --save react-native-web-player
Then:
import WebPlayer from 'react-native-web-player'
export default () => (
<WebPlayer
style={{width: 800, height: 500}}
/>
)This component is a simple wrapper around the iframe that handles encoding parameters for you. While it passes most props along to the iframe, it has a few extra props:
style- The style of thedivwhich wraps theiframe(the iframe has100%width and height).className- The className of thedivwhich wraps theiframe.baseURL- Optionally, specify a custom url to load the player from. This url should not include a hash. Defaults to the//cdn.rawgit.comurl as described below.
A umd build of this React component is available in the dist directory.
If you're not using React, include the web player in an iframe.
<iframe width="880" height="425" frameborder="0" src="//cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html"></iframe>The React component accepts the following props. Props don't need to be URI-encoded or JSON-encoded, as this is handled automatically.
The iframe accepts the following parameters after the hash in the url. You must URI encode every parameter.
code- The code to show/run in the player. Defaults to the sample app.title- An optional title for the player. By default, there is no title.width- The width of the device. Defaults to210.scale- Zoom the device screen. Defaults to1.platform- One ofiosorandroid. Defaults toios. Currently this changes the phone image, but may also have an effect on how the code is executed in the future.entry- The filename of the entry file. This is only relevant when showing multiple files with thefilesparameter. Defaults toindex.js.initialTab- The filename of the tab to show by default. This is only relevant when showing multiple files with thefilesparameter. Defaults toindex.js.fullscreen- Show a button to enable fullscreen editing. Defaults tofalse. Note that the iframe must have theallowfullscreenattribute for this to work.assetRoot- Specifies the root url for assetrequires. E.g. to requirehttp://localhost:8080/images/hello.png, you could setassetRootto'http://localhost:8080/'and writerequire('./images/hello.png')in your code.transpilerTitle- An optional title for the transpiler output pane. By default, there is no title.playerTitle- An optional title for the player pane. By default, there is no title.workspaceCSS- An optional CSS string to apply to the workspaceiframe.playerCSS- An optional CSS string to apply to the player'siframe.playerStyleSheet- One ofresetornone. Whenreset, the meyerweb CSS reset is applied to the player'siframe. Defaults toreset.
When using the iframe directly, the following parameters must be JSON encoded and then also URI encoded:
-
files- Array of files to show, one per tab. The format is an array of 2-element arrays, where the first element is the filename (e.g.index.js) and the second is the code.Example usage:
[['index.js', 'console.log(1)'], ['foo.js', 'console.log(2)']]Files may be required from one another by name. E.g. if the files are
index.jsandhelpers.js, in the code ofindex.jsyou may writeimport Foo from './helpers'to use its default export.Use the
entryandinitialTabparameters to control which file is executed first and which tab is shown by default. -
panes- Array of panes to show. Each element is one of:editor,player,transpiler.The default value is:
['editor', 'player'] -
vendorComponents- Array of 3rd party components to make available to the sandbox. The format is an array of either 2-element or 3-element arrays.-
To use a CommonJS
require-style loader, pass a 2-element array, where the first element is therequire()name, and the second is the source url. E.g. to load moment.js: setvendorComponentsto the value[['moment', 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js']] -
To load a component as a property on
window, pass a 3-element array, where the first element is therequire()name, the second element is the window property name (e.g.window.moment), and the third element is the source url. E.g. to load moment.js: setvendorComponentsto the value[['moment', 'moment', 'https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.min.js']]
-
-
styles- An object containing style objects. If you're familiar with React Native, this is thefooinStyleSheet.create(foo). Styles passed will be vendor-prefixed automatically. The following named styles can be used to override default styling.headerheaderTexttabtabTexttabTextActivetranspilerHeadertranspilerHeaderTextplayerPaneplayerHeaderplayerHeaderText
Example usage:
{header: {backgroundColor: 'red'}}
When used as an iframe, the easiest way to set the code parameter is to edit the code in the web player and copy and paste the url when you're done (the url updates automatically as you type).
Alternately, you can manually url-encode the parameters. You can do so programmatically or via the JavaScript console.
encodeURIComponent('Hello World')
# => "Hello%20World"This project contains static assets that run standalone in the browser. You don't need a server, unless you want to host the assets yourself.
The recommended host is rawgit + MaxCDN. MaxCDN is highly performant and serves over http and https. The examples in this readme all point to:
<iframe width="880" height="425" frameborder="0" src="//cdn.rawgit.com/dabbott/react-native-web-player/v2.0.0-alpha.4/index.html"></iframe>If you prefer, you may access the gh-pages branch directly. This has the advantage of always serving you the latest version, but the drawback of potentially failing on major API changes (along with slower download speeds for the assets).
<iframe width="880" height="425" frameborder="0" src="//dabbott.github.io/react-native-web-player/"></iframe>- Custom code - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#platform=ios&code=import%20React%2C%20%7B%20Component%2C%20%7D%20from%20'react'%3B%0Aimport%20%7B%20AppRegistry%2C%20Text%2C%20%7D%20from%20'react-native'%3B%0A%0Aconst%20App%20%3D%20()%20%3D%3E%20%3CText%3EHello%20World%3C%2FText%3E%3B%0A%0AAppRegistry.registerComponent('App'%2C%20()%20%3D%3E%20App)%3B
- Android device - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#platform=android
- Custom title - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#title=Hello%20Title
- Load moment.js - https://cdn.rawgit.com/dabbott/react-native-web-player/gh-v2.0.0-alpha.4/index.html#title=moment.js&vendorComponents=%5B%5B%22moment%22%2C%20%22moment%22%2C%20%22https%3A%2F%2Fcdnjs.cloudflare.com%2Fajax%2Flibs%2Fmoment.js%2F2.14.1%2Fmoment.min.js%22%5D%5D&code=import%20React%2C%20%7B%20Component%2C%20%7D%20from%20'react'%3B%0Aimport%20%7B%0A%20%20AppRegistry%2C%0A%20%20StyleSheet%2C%0A%20%20Text%2C%0A%20%20View%2C%0A%7D%20from%20'react-native'%3B%0A%0Aconst%20moment%20%3D%20require('moment')%0A%0Aclass%20App%20extends%20Component%20%7B%0A%20%20render()%20%7B%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%3CView%20style%3D%7Bstyles.container%7D%3E%0A%20%20%20%20%20%20%20%20%3CText%20style%3D%7Bstyles.welcome%7D%3E%0A%20%20%20%20%20%20%20%20%20%20%7Bmoment().format('MMMM%20Do%20YYYY%2C%20h%3Amm%3Ass%20a')%7D%0A%20%20%20%20%20%20%20%20%3C%2FText%3E%0A%20%20%20%20%20%20%3C%2FView%3E%0A%20%20%20%20)%3B%0A%20%20%7D%0A%7D%0A%0Aconst%20styles%20%3D%20StyleSheet.create(%7B%0A%20%20container%3A%20%7B%0A%20%20%20%20flex%3A%201%2C%0A%20%20%20%20justifyContent%3A%20'center'%2C%0A%20%20%20%20alignItems%3A%20'center'%2C%0A%20%20%20%20backgroundColor%3A%20'%23F5FCFF'%2C%0A%20%20%7D%2C%0A%20%20welcome%3A%20%7B%0A%20%20%20%20fontSize%3A%2016%2C%0A%20%20%20%20textAlign%3A%20'center'%2C%0A%20%20%20%20margin%3A%2010%2C%0A%20%20%7D%2C%0A%7D)%3B%0A%0AAppRegistry.registerComponent('App'%2C%20()%20%3D%3E%20App)%3B
React/Redux To-do list with persistence
Transpiled output for ES6 const and let
These examples are taken from React Native Express.
Advanced examples tend to have extremely long URLs which load successfully in an iframe but sometimes fail to load when opened by clicking a link.
npm install
npm run start
=> localhost:8080
npm run build
First publish to npm.
npm version (major|minor|patch)
npm publish
Then publish to gh-pages and make a special tagged release for hosting via CDN.
# Point to the latest release
make TAG=v2.0.0-alpha.4
BSD