React Native for Web配置

兼容性:React Native 0.55。

“React Native for Web”使得可以使用React DOM在Web上运行React Native组件和API。查看在Web上运行的React Native示例的实时演示。

  • 高质量的Web界面:可以轻松地在JavaScript中创建fast,自适应的Web UI。它提供原生质量的交互,支持多种输入模式(触摸,鼠标,键盘),优化的供应商前缀样式,内置支持RTL布局,内置可访问性,并与React Dev Tools集成。
  • 编写一次,随处渲染:与现有的React DOM组件互操作,并与大多数React Native API兼容。您可以为本机和Web开发新组件,而无需重写现有代码。React Native for Web也可以使用Node.js渲染到服务器上的HTML和关键CSS。

浏览器支持:Chrome,Firefox,Edge,Safari 7 +,IE 10+。

快速开始

最简单的入门方法是编辑此 CodeSandbox模板(或 Glitch)。你不需要安装任何东西来试试。

有关安装和配置的详细信息,请阅读入门 指南。

文档

有关整体API,设计详细信息以及有关手势响应程序系统 和动画的信息,请参阅React Native文档。

某些组件和API通过Web的其他功能进行了扩展。在少数情况下,网络上缺少Android或iOS的功能。这些差异记录在网站上。

入门 Webpack,看这篇就够了

.babelrc 

{
"presets": [
"@babel/preset-env",
    "@babel/preset-react",
    "react-native"
  ],
  "plugins": [
    ["module-resolver", {
"alias": {
"^react-native$": "react-native-web"
      }
    }]
  ]
}

 

package.json 

{
"name": "rnweb",
  "version": "0.0.1",
  "private": true,
  "scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
    "ios": "react-native run-ios",
    "android": "react-native run-android",
    "webdev": "./node_modules/.bin/webpack-dev-server -d --config ./web/webpack.config.js --inline --hot --colors",
    "webprod": "./node_modules/.bin/webpack -p --config ./web/webpack.config.js",
    "test": "jest"
  },
  "dependencies": {
"@babel/runtime": "^7.4.4",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-native": "0.59.8",
    "react-native-web": "^0.11.2"
  },
  "devDependencies": {
"@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.4",
    "@babel/plugin-transform-runtime": "^7.4.4",
    "@babel/preset-env": "^7.4.4",
    "@babel/preset-react": "^7.0.0",
    "babel-jest": "^24.8.0",
    "babel-loader": "^8.0.6",
    "babel-plugin-module-resolver": "^3.2.0",
    "babel-plugin-react-native-web": "^0.11.2",
    "babel-preset-react-native": "^5.0.2",
    "jest": "^24.8.0",
    "make-dir-cli": "^2.0.0",
    "react-test-renderer": "16.8.3",
    "source-map-loader": "^0.2.4",
    "url-loader": "^1.1.2",
    "webpack": "^4.31.0",
    "webpack-cli": "^3.3.2",
    "webpack-dev-server": "^3.3.1"
  },
  "jest": {
"preset": "react-native"
  }
}

pasting


 

web/webpack.config.js

/**
 * @Name webpack.config.js
 * @Description react-native-web webpack打包配置文件
 */
const path = require('path');
const webpack = require('webpack');

/** __dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录 */
const appDirectory = path.resolve(__dirname, '../');

/**
 * Babel其实是一个编译JavaScript的平台
 * 1、使用最新的JavaScript代码(ES6,ES7...)而不用管新标准是否被当前使用的浏览器完全支持
 * 2、使用基于JavaScript进行了拓展的语言,比如React的JSX;
 * */
const babelLoaderConfiguration = {
/** 正则表达式,编译所有.js文件 */
  test: /\.js$/,
  /** 包含要编译的目录和文件 */
  include: [
/** 根目录下的index.js */
    path.resolve(appDirectory, 'index.js'),
    /** 子目录src下所有文件 */
    path.resolve(appDirectory, 'src'),
    path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
  ],
  use: {
loader: 'babel-loader',
    /** webpack会自动调用.babelrc里的babel配置选项 */
    options: {
cacheDirectory: true,
      // presets: ['react-native'],
      // plugins: ['react-native-web']
    }
  }
};

const imageLoaderConfiguration = {
test: /\.(gif|jpe?g|png|svg)$/,
  use: {
/**
     * file-loader解决路径问题,url-loader根据limit值对图片编码,生成dataURl
     * url-loader内置了file-loader
     * */
    loader: 'url-loader',
    options: {
name: '[name].[ext]'
    }
  }
};

module.exports = {
/** webpack4.x增加的选项,development/production */
  mode: process.env.NODE_ENV || 'production',
  /** 开发时调试源码,会影响编译速度,生产环境请注释该行 */
  devtool: 'eval-source-map',
  /** entry入口 */
  entry: [
    path.resolve(appDirectory, 'index.js'),
  ],
  /** output出口 */
  output: {
/** 打包后输出文件的文件名 */
    filename: 'bundle.web.js',
    /** 打包后的文件存放的地方 */
    path: path.resolve(appDirectory, 'dist')
  },
  /**
   * 通过使用不同的loader,webpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理。
   * 比如分析转换scss为css,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件,
   * 对React的开发而言,合适的Loaders可以把React的中用到的JSX文件转换为JS文件。
   * loader配置选项参数说明:
   *  test:一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)
   *  loader:loader的名称(必须)
   *  include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(可选)
   *  query:为loaders提供额外的设置选项(可选)
   * */
  module: {
rules: [
      babelLoaderConfiguration,
      imageLoaderConfiguration
    ]
  },

  /**
   * resolve配置模块如何解析
   * */
  resolve: {
alias: {
'react-native$': 'react-native-web'
    },
    /** 自动解析确定的扩展 */
    extensions: ['.web.js', '.js'],
    /** 告诉webpack解析模块时应搜索的目录 */
    modules: ['node_modules']
  },
  /**
   * 使用webpack构建本地服务器
   * npm install --save-dev webpack-dev-server
   * yarn add -D webpack-dev-server
   * http://localhost:8080
   * */
  devServer: {
/** 本地服务器所加载的页面所在的目录 */
    contentBase: "./dist",
    /** true所有的跳转将指向index.html */
    historyApiFallback: true,
    /** 当源文件改变时实时刷新 */
    inline: true
  }

};

web/index.html 

<!DOCTYPE html>
<html lang="en" style="height:100%">
<head>
  <meta charset="UTF-8">
  <title>React Native Web In Superbuy App</title>
  <meta name="viewport" content="initial-scale=1.0,width=device-width">
  <style>
    html, body { height: 100%; width: 100%; overflow: hidden; }
    .react-app { height: 100%; overflow: hidden; }
</style>
</head>
<body style="height:100%">
  <div id="react-app" style="display:flex;height:100%"></div>
  <script src="./bundle.web.js"></script>
</body>
</html>

index.js

import {AppRegistry, Platform} from 'react-native';
import App from './src/App';
import {name as appName} from './app.json';

// register the app
AppRegistry.registerComponent(appName, () => App);

if (Platform.OS === 'web') {
AppRegistry.runApplication(appName, {
initialProps: {},
    rootTag: document.getElementById('react-app')
  });
}