From d9f04040917c4c4a1d072fe8d5b1d3942412bfd9 Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Mon, 15 Aug 2016 13:48:12 +0800 Subject: [PATCH 01/10] Add react-dom to support react-web later --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 01605a61..fc64afa7 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "query-string": "^4.2.2", "react": "15.1.0", "react-addons-pure-render-mixin": "15.1.0", + "react-dom": "15.1.0", "react-native": "^0.28.0", "react-native-barcodescanner": "^3.0.0", "react-native-blur": "^1.0.0", From 21c4a20fbab67f1b4102f6f8899b45258bf9b091 Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Mon, 15 Aug 2016 10:13:31 +0800 Subject: [PATCH 02/10] npm install -g react-web-cli; cd ..; mv noder-react-native noder; react-web init noder; mv noder noder-react-native --- package.json | 13 ++++++- web/webpack.config.js | 79 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 web/webpack.config.js diff --git a/package.json b/package.json index fc64afa7..685aa796 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "react-native-scrollable-tab-view": "^0.5.1", "react-native-vector-icons": "^2.0.3", "react-redux": "^4.4.5", + "react-web": "0.3.2", "redux": "^3.5.2", "redux-actions": "^0.10.0", "redux-logger": "^2.6.1", @@ -44,6 +45,10 @@ }, "devDependencies": { "babel-eslint": "^6.1.0", + "babel-loader": "^6.2.4", + "babel-preset-es2015": "^6.6.0", + "babel-preset-react": "^6.5.0", + "babel-preset-stage-1": "^6.5.0", "coffee-script": "^1.9.2", "dev-ip": "^1.0.1", "eslint": "^2.13.1", @@ -51,9 +56,15 @@ "gulp": "^3.9.1", "gulp-replace": "^0.5.4", "gulp-util": "^3.0.4", + "haste-resolver-webpack-plugin": "^0.2.1", + "json-loader": "^0.5.4", + "react-hot-loader": "^1.3.0", "react-native-cli": "^0.2.0", "redux-devtools": "^3.3.1", - "run-sequence": "^1.2.1" + "run-sequence": "^1.2.1", + "webpack": "^1.13.1", + "webpack-dev-server": "^1.14.1", + "webpack-html-plugin": "^0.1.1" }, "devEngines": { "node": ">= 4.x", diff --git a/web/webpack.config.js b/web/webpack.config.js new file mode 100644 index 00000000..6d9ec5b1 --- /dev/null +++ b/web/webpack.config.js @@ -0,0 +1,79 @@ +'use strict'; + +var path = require('path'); +var webpack = require('webpack'); +var HtmlPlugin = require('webpack-html-plugin'); +var HasteResolverPlugin = require('haste-resolver-webpack-plugin'); + +var IP = '0.0.0.0'; +var PORT = 3000; +var NODE_ENV = process.env.NODE_ENV; +var ROOT_PATH = path.resolve(__dirname, '..'); +var PROD = 'production'; +var DEV = 'development'; +let isProd = NODE_ENV === 'production'; + +var config = { + paths: { + src: path.join(ROOT_PATH, '.'), + index: path.join(ROOT_PATH, 'index.ios'), + }, +}; + +module.exports = { + ip: IP, + port: PORT, + devtool: 'source-map', + resolve: { + alias: { + 'react-native': 'ReactWeb', + }, + extensions: ['', '.js', '.jsx'], + }, + entry: isProd? [ + config.paths.index + ]: [ + 'webpack-dev-server/client?http://' + IP + ':' + PORT, + 'webpack/hot/only-dev-server', + config.paths.index, + ], + output: { + path: path.join(__dirname, 'output'), + filename: 'bundle.js' + }, + plugins: [ + new HasteResolverPlugin({ + platform: 'web', + nodeModules: ['react-web'] + }), + new webpack.DefinePlugin({ + 'process.env': { + 'NODE_ENV': JSON.stringify(isProd? PROD: DEV), + } + }), + isProd? new webpack.ProvidePlugin({ + React: "react" + }): new webpack.HotModuleReplacementPlugin(), + new webpack.NoErrorsPlugin(), + new HtmlPlugin(), + ], + module: { + loaders: [{ + test: /\.json$/, + loader: 'json', + }, { + test: /\.jsx?$/, + loader: 'react-hot', + include: [config.paths.src], + exclude: [/node_modules/] + }, { + test: /\.jsx?$/, + loader: 'babel', + query: { + presets: ['es2015', 'react', 'stage-1'] + }, + include: [config.paths.src], + exclude: [/node_modules/] + }] + } +}; From 601b6af30ec1fd000e7347a8916d8add246aaf2d Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Mon, 15 Aug 2016 14:31:21 +0800 Subject: [PATCH 03/10] `react-web bundle` worked well --- .eslintignore | 2 ++ .gitignore | 4 ++++ README.md | 1 + index.web.js | 13 +++++++++++++ package.json | 2 ++ post_npm_install.sh | 10 ++++++++++ post_npm_install/react-native-blur/src/BlurView.js | 3 +++ .../react-native-blur/src/VibrancyView.js | 3 +++ .../react-native-scrollable-tab-view/Button.js | 3 +++ web/webpack.config.js | 7 +++++-- 10 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 .eslintignore create mode 100644 index.web.js create mode 100755 post_npm_install.sh create mode 100644 post_npm_install/react-native-blur/src/BlurView.js create mode 100644 post_npm_install/react-native-blur/src/VibrancyView.js create mode 100644 post_npm_install/react-native-scrollable-tab-view/Button.js diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..1ac595da --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +/node_modules/ +/web/output/ diff --git a/.gitignore b/.gitignore index 9b25b931..a6ff951f 100755 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,10 @@ project.xcworkspace .gradle local.properties +# Web +# +/web/output/ + # node.js # node_modules/ diff --git a/README.md b/README.md index d0f9dd73..12cd810f 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ For local development you need to follow the below commands: ``` git clone https://github.com/soliury/noder-react-native.git npm install +./post_npm_install.sh ``` diff --git a/index.web.js b/index.web.js new file mode 100644 index 00000000..4aa09350 --- /dev/null +++ b/index.web.js @@ -0,0 +1,13 @@ +import React from 'react'; +import {AppRegistry} from 'react-native'; +import Noder from './src'; + + +AppRegistry.registerComponent('noder', () => Noder); + +var app = document.createElement('div'); +document.body.appendChild(app); + +AppRegistry.runApplication('noder', { + rootTag: app +}); diff --git a/package.json b/package.json index 685aa796..188ba0f9 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "dev-ip": "^1.0.1", "eslint": "^2.13.1", "eslint-plugin-react": "^5.2.2", + "file-loader": "^0.9.0", "gulp": "^3.9.1", "gulp-replace": "^0.5.4", "gulp-util": "^3.0.4", @@ -62,6 +63,7 @@ "react-native-cli": "^0.2.0", "redux-devtools": "^3.3.1", "run-sequence": "^1.2.1", + "url-loader": "^0.5.7", "webpack": "^1.13.1", "webpack-dev-server": "^1.14.1", "webpack-html-plugin": "^0.1.1" diff --git a/post_npm_install.sh b/post_npm_install.sh new file mode 100755 index 00000000..82b01eb1 --- /dev/null +++ b/post_npm_install.sh @@ -0,0 +1,10 @@ +#!/bin/bash +# patch some node_modules to build well + +if [ ! -d node_modules ]; then + npm install +fi + +# react-web can't recognize *.android.js and *.ios.js now, so be it +cp post_npm_install/react-native-blur/src/* node_modules/react-native-blur/src/ +cp post_npm_install/react-native-scrollable-tab-view/Button.js node_modules/react-native-scrollable-tab-view/ diff --git a/post_npm_install/react-native-blur/src/BlurView.js b/post_npm_install/react-native-blur/src/BlurView.js new file mode 100644 index 00000000..2d2c0b0a --- /dev/null +++ b/post_npm_install/react-native-blur/src/BlurView.js @@ -0,0 +1,3 @@ +import {Platform} from 'react-native'; + +module.exports = Platform.OS === 'web' ? require('./BlurView.ios') : require('./BlurView.' + Platform.OS); diff --git a/post_npm_install/react-native-blur/src/VibrancyView.js b/post_npm_install/react-native-blur/src/VibrancyView.js new file mode 100644 index 00000000..2046710b --- /dev/null +++ b/post_npm_install/react-native-blur/src/VibrancyView.js @@ -0,0 +1,3 @@ +import {Platform} from 'react-native'; + +module.exports = Platform.OS === 'web' ? require('./VibrancyView.ios') : require('./VibrancyView.' + Platform.OS); diff --git a/post_npm_install/react-native-scrollable-tab-view/Button.js b/post_npm_install/react-native-scrollable-tab-view/Button.js new file mode 100644 index 00000000..71ec0031 --- /dev/null +++ b/post_npm_install/react-native-scrollable-tab-view/Button.js @@ -0,0 +1,3 @@ +import {Platform} from 'react-native'; + +module.exports = Platform.OS === 'web' ? require('./Button.ios') : require('./Button.' + Platform.OS); diff --git a/web/webpack.config.js b/web/webpack.config.js index 6d9ec5b1..baa0f7e4 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -16,7 +16,7 @@ let isProd = NODE_ENV === 'production'; var config = { paths: { src: path.join(ROOT_PATH, '.'), - index: path.join(ROOT_PATH, 'index.ios'), + index: path.join(ROOT_PATH, 'index.web'), }, }; @@ -73,7 +73,10 @@ module.exports = { presets: ['es2015', 'react', 'stage-1'] }, include: [config.paths.src], - exclude: [/node_modules/] + exclude: [/(node_modules\/(?!react))/, path.join(ROOT_PATH, 'post_npm_install')] + }, { + test : /\.(png|gif|svg|jpg)$/, + loader : 'url-loader?limit=8192' }] } }; From 0bdd163c6c04c303435f597c9d97cce82f43adef Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Mon, 15 Aug 2016 14:33:28 +0800 Subject: [PATCH 04/10] Let JavaScript source map debugging not just locate to bundle.js but the real source file --- web/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/webpack.config.js b/web/webpack.config.js index baa0f7e4..29e0e947 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -23,7 +23,7 @@ var config = { module.exports = { ip: IP, port: PORT, - devtool: 'source-map', + devtool: 'cheap-module-eval-source-map', resolve: { alias: { 'react-native': 'ReactWeb', From be22b4e45c9c03e3e2fd5f7ca6e63abbfc0c3f8d Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Mon, 15 Aug 2016 14:41:47 +0800 Subject: [PATCH 05/10] Fix `react-web start` "Uncaught ReferenceError: regeneratorRuntime is not defined" by https://babeljs.io/docs/usage/polyfill/ --- index.web.js | 2 +- package.json | 1 + web/webpack.config.js | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/index.web.js b/index.web.js index 4aa09350..c163b595 100644 --- a/index.web.js +++ b/index.web.js @@ -1,4 +1,4 @@ -import React from 'react'; +import 'babel-polyfill'; import {AppRegistry} from 'react-native'; import Noder from './src'; diff --git a/package.json b/package.json index 188ba0f9..5e8b681c 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "devDependencies": { "babel-eslint": "^6.1.0", "babel-loader": "^6.2.4", + "babel-polyfill": "^6.13.0", "babel-preset-es2015": "^6.6.0", "babel-preset-react": "^6.5.0", "babel-preset-stage-1": "^6.5.0", diff --git a/web/webpack.config.js b/web/webpack.config.js index 29e0e947..87c445b2 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -31,8 +31,10 @@ module.exports = { extensions: ['', '.js', '.jsx'], }, entry: isProd? [ + 'babel-polyfill', config.paths.index ]: [ + 'babel-polyfill', 'webpack-dev-server/client?http://' + IP + ':' + PORT, 'webpack/hot/only-dev-server', config.paths.index, From c8e8eaf8630c66dd643b97eb892c166b24cfa59d Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Thu, 4 Aug 2016 09:26:56 +0800 Subject: [PATCH 06/10] Fix `react-web start` "Uncaught ReferenceError: __DEV__ is not defined" --- web/webpack.config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/web/webpack.config.js b/web/webpack.config.js index 87c445b2..9dfeb7ed 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -51,7 +51,8 @@ module.exports = { new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.stringify(isProd? PROD: DEV), - } + }, + '__DEV__': !isProd }), isProd? new webpack.ProvidePlugin({ React: "react" From 4a07577e29ab1d9ebff7a28eec4544e878434e12 Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Tue, 16 Aug 2016 10:06:51 +0800 Subject: [PATCH 07/10] `react-web start` worked well --- README.md | 7 ++++++- package.json | 2 +- post_npm_install.sh | 5 ++++- src/components/base/Modal.js | 4 +++- src/layouts/Login.js | 32 ++++++++++++++++++------------ src/layouts/QRCode.js | 19 ++++++++++++++++-- src/layouts/Utils.js | 38 +++++++++++++++++++++++------------- 7 files changed, 74 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index 12cd810f..9f4ddeb4 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ npm install Click the run button in Xcode, if something went wrong, you need to rebuild all packages that be used in this project with Xcode (Just select the package and press **command+B** to run compile). -If you want to run it on you iPhone, please follow the [Offical Doc](http://facebook.github.io/react-native/docs/runningondevice.html#content). +If you want to run it on your iPhone, please follow the [Offical Doc](http://facebook.github.io/react-native/docs/runningondevice.html#content). If you don't want to update the ip manually, please run: @@ -39,6 +39,11 @@ npm start The ip will be replaced automatically. +If you want to run it on your Browser (localhost:3000), please run: +``` +react-web start +``` + ## Screenshots diff --git a/package.json b/package.json index 5e8b681c..be990414 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "react-native-scrollable-tab-view": "^0.5.1", "react-native-vector-icons": "^2.0.3", "react-redux": "^4.4.5", - "react-web": "0.3.2", + "react-web": "git+https://github.com/flyskywhy/react-web.git", "redux": "^3.5.2", "redux-actions": "^0.10.0", "redux-logger": "^2.6.1", diff --git a/post_npm_install.sh b/post_npm_install.sh index 82b01eb1..15600f27 100755 --- a/post_npm_install.sh +++ b/post_npm_install.sh @@ -1,5 +1,5 @@ #!/bin/bash -# patch some node_modules to build well +# patch some node_modules to build and run well if [ ! -d node_modules ]; then npm install @@ -8,3 +8,6 @@ fi # react-web can't recognize *.android.js and *.ios.js now, so be it cp post_npm_install/react-native-blur/src/* node_modules/react-native-blur/src/ cp post_npm_install/react-native-scrollable-tab-view/Button.js node_modules/react-native-scrollable-tab-view/ + +# looks like a BUG +sed -i "s/export default parseHtml = function (html, done) {/export default function (html, done) {/" node_modules/react-native-html-render/lib/htmlParse.js diff --git a/src/components/base/Modal.js b/src/components/base/Modal.js index 0f177cc4..431f09f2 100644 --- a/src/components/base/Modal.js +++ b/src/components/base/Modal.js @@ -1,6 +1,8 @@ import React, {Component, PropTypes} from 'react'; import {Dimensions, View, StyleSheet, Animated, Easing, Platform, TouchableWithoutFeedback, findNodeHandle} from 'react-native'; -import {BlurView} from 'react-native-blur'; +if (Platform.OS !== 'web') { + var BlurView = require('react-native-blur').BlurView; +} const {height, width} = Dimensions.get('window'); diff --git a/src/layouts/Login.js b/src/layouts/Login.js index d4543ec7..2203cc40 100644 --- a/src/layouts/Login.js +++ b/src/layouts/Login.js @@ -1,5 +1,6 @@ import React, {Component, PropTypes} from 'react'; import { + Platform, View, Text, TouchableHighlight, @@ -10,7 +11,11 @@ import { TouchableOpacity } from 'react-native'; import Icon from 'react-native-vector-icons/Ionicons'; -import Camera from 'react-native-camera'; + +if (Platform.OS !== 'web') { + var Camera = require('react-native-camera'); +} + import Spinner from '../components/base/Spinner'; import packageObj from '../../package.json'; @@ -21,18 +26,19 @@ class Login extends Component { _onLoginPress() { const {ui, router, actions} = this.props; if (ui.checkTokenPending) return; - Camera.checkDeviceAuthorizationStatus() - .then((isAuth)=> { - if (isAuth) { - router.toQRCode(); - } - else { - actions.toast('请在设置中开启Noder对相机的访问'); - } - }) - .catch((err)=> { - actions.toast('获取相机访问权错误'); - }); + if (Platform.OS !== 'web') { + Camera.checkDeviceAuthorizationStatus() + .then((isAuth) => { + if (isAuth) { + router.toQRCode(); + } else { + actions.toast('请在设置中开启Noder对相机的访问'); + } + }) + .catch((err) => { + actions.toast('获取相机访问权错误'); + }); + } } diff --git a/src/layouts/QRCode.js b/src/layouts/QRCode.js index 2c73d093..1c8fb165 100644 --- a/src/layouts/QRCode.js +++ b/src/layouts/QRCode.js @@ -1,7 +1,11 @@ import React, {Component} from 'react'; import {StyleSheet, View, Text, Dimensions, Platform, TouchableOpacity, Vibration} from 'react-native'; -import Camera from 'react-native-camera'; -import BarcodeScanner from 'react-native-barcodescanner'; + +if (Platform.OS !== 'web') { + var Camera = require('react-native-camera'); + var BarcodeScanner = require('react-native-barcodescanner'); +} + import Icon from 'react-native-vector-icons/Ionicons'; import OverlayButton from '../components/base/OverlayButton'; @@ -54,6 +58,17 @@ class QRCode extends Component { ); + // for web + if (Platform.OS === 'web') { + return ( + + + 只有原生 APP 才支持二维码 + + + ); + } + // for android if (Platform.OS === 'android') { return ( diff --git a/src/layouts/Utils.js b/src/layouts/Utils.js index c17d556d..9ecdd502 100644 --- a/src/layouts/Utils.js +++ b/src/layouts/Utils.js @@ -1,5 +1,5 @@ import React, {Component} from 'react'; -import {View, StyleSheet, Text, StatusBar, AppState} from 'react-native'; +import {Platform, View, StyleSheet, Text, StatusBar, AppState} from 'react-native'; import Toast from '../components/base/Toast'; import * as codePushUtils from '../utils/codePushSync'; @@ -12,13 +12,15 @@ class Utils extends Component { actions.getUnreadMessageCount(); } }); - codePushUtils.sync(); - AppState.addEventListener("change", (newState) => { - if (newState === "active") { - codePushUtils.sync(); - this.props.user.secret && actions.getUnreadMessageCount(); - } - }); + if (Platform.OS !== 'web') { + codePushUtils.sync(); + AppState.addEventListener("change", (newState) => { + if (newState === "active") { + codePushUtils.sync(); + this.props.user.secret && actions.getUnreadMessageCount(); + } + }); + } // if (__DEV__) { // actions.checkToken('your secretKey', ()=> { @@ -36,12 +38,20 @@ class Utils extends Component { render() { - return ( - - - this.toast=view }/> - - ); + if (Platform.OS === 'web') { + return ( + + this.toast=view }/> + + ); + } else { + return ( + + + this.toast=view }/> + + ); + } } } From a9b43ed0c90b07739100ead8f304bc1b191ee039 Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Tue, 16 Aug 2016 10:20:29 +0800 Subject: [PATCH 08/10] `npm run web` and `npm run build-web` worked well --- package.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/package.json b/package.json index be990414..86a86feb 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "start": "node node_modules/react-native/local-cli/cli.js start", "android": "node node_modules/react-native/local-cli/cli.js run-android", "ios": "node node_modules/react-native/local-cli/cli.js run-ios", + "web": "node node_modules/react-web/local-cli/cli.js start web/webpack.config.js", "log": "adb logcat *:S ReactNative:V ReactNativeJS:V", + "build-web": "node node_modules/react-web/local-cli/cli.js bundle web/webpack.config.js", "build-ios": "react-native unbundle --entry-file index.ios.js --platform ios --dev false", "build-android": "cd android && ./gradlew assembleRelease && open app/build/outputs/apk && cd ..", "checkversion": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json", From 0f2a586e1ad1849978f9200f3c7e1d88cf1ae2a2 Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Wed, 10 Aug 2016 16:29:00 +0800 Subject: [PATCH 09/10] Use with https://github.com/zalmoxisus/redux-devtools-extension --- src/store/configureStore.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store/configureStore.js b/src/store/configureStore.js index ba31c34a..28826eaf 100644 --- a/src/store/configureStore.js +++ b/src/store/configureStore.js @@ -34,7 +34,7 @@ if (isDebuggingInChrome) { export default function configureStore(initialState) { const store = applyMiddleware( ...middlewares - )(createStore)(reducers, initialState); + )(createStore)(reducers, initialState, window.devToolsExtension && window.devToolsExtension()); if (module.hot) { module.hot.accept(() => { From f5c2d839dd33ed97aae480fcf5c9adccf4b44de4 Mon Sep 17 00:00:00 2001 From: Li Zheng Date: Tue, 16 Aug 2016 16:52:48 +0800 Subject: [PATCH 10/10] Fix a BUG in node_modules/react-native-html-render/lib/htmlRender.js --- post_npm_install.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/post_npm_install.sh b/post_npm_install.sh index 15600f27..45a94fd8 100755 --- a/post_npm_install.sh +++ b/post_npm_install.sh @@ -11,3 +11,4 @@ cp post_npm_install/react-native-scrollable-tab-view/Button.js node_modules/reac # looks like a BUG sed -i "s/export default parseHtml = function (html, done) {/export default function (html, done) {/" node_modules/react-native-html-render/lib/htmlParse.js +sed -i "s/ uri = node.attribs.href;/ let uri = node.attribs.href;/" node_modules/react-native-html-render/lib/htmlRender.js