摘要:尽管 React Native 已经进入开源的第 6 个年头,距离发布 1.0 版本依旧是遥遥无期。“Learn once, write anywhere”,完全不影响 React Native 沦为“不会 JavaScript 也能用”的框架,那如何将在 React Native 项目中引入 react-native-web 呢?

react-native-web 简介

仓库地址: https://github.com/necolas/react-native-web

react-native-web 是由 前 Twitter 现 Facebook 工程师 Nicolas Gallagher 实现并维护的开源项目,是一个使 React Native 组件和 API 能运行在 Web 上的库,其和 React Native Windows, React Native macOS 等库将 React Native 拓展到一个又一个新的平台。目前推特、expo、大联盟足球、Flipkart、优步、《泰晤士报》、DataCamp 以及我们小作坊都在生产中使用了 react-native-web。Chrome、Firefox、Edge,Safari 7 +、IE 10+都支持通过 react-native-web 构建的 web 应用。当然值得注意的是,官方文档明确表示不支持 React Native 中不推荐使用的组件和 API,因此如果您项目中的某些功能依赖第三方库,可能那部分的功能在 web 端同构时需要额外处理。

浅显地认为react-native-web就是把React Native的组件和API都用适用于Web的标签和API再适配实现一遍,使其在Web上的行为和在原生应用上尽量保持一致,从文档中提到的 Alert 和 Setting 模块以及其对应的源码中大概能感受到一二,比如TextInput:

  switch (keyboardType) {case 'email-address':type = 'email';break;case 'number-pad':case 'numeric':inputMode = 'numeric';break;case 'decimal-pad':inputMode = 'decimal';break;case 'phone-pad':type = 'tel';break;case 'search':case 'web-search':type = 'search';break;case 'url':type = 'url';break;default:type = 'text';}if (secureTextEntry) {type = 'password';}

因此也借鉴了 React Native 的一些代码,作为适配的依据。

如果您想基于 React Native 实现多端统一化方案,可参考去哪儿前端团队的实现方案:跨端开发, 仓库地址:https://github.com/qunarcorp/qrn-remax-unir

添加到React Native项目

一般来说新建 React Native 项目时可以选用 expo-cli 或者 react-native-cli 来创建。expo-cli 中已经预置了对web的支持,如下图所示.

而我们实际开发中可能用 react-native-cli脚手架来构建项目比较多些,那么如何引入 react-native-web呢?

我们先初始化项目:

npx react-native init rn_web
# 当然也可以使用模板,如
# npx react-native init rn_web --template react-native-template-typescript

此时我们的项目并不支持在web中使用:

为了项目能在web环境中运行,我们需要借助今天的主角--react-native-web,有请主角出台:

cd rn_web
yarn add react-native-web
yarn add -D babel-plugin-react-native-web webpack webpack-cli webpack-dev-server html-webpack-plugin react-dom babel-loader url-loader @svgr/webpack

接着我们施展Copy大法,将我们初始化能用到的App.web.jsx、index.html、index.web.js、webpack.config.js这几个文件一把 down下来:

curl -L https://gist.github.com/hu-qi/bde8a6d2b45325d93b1665174f938faa/download | tar -xvz --strip-components=1

react-native-web

然后在package.json中添加build和web的脚本:

"build": "rm -rf dist/ && webpack --mode=production --config webpack.config.js",
"web": "webpack serve --mode=development --config webpack.config.js"

就和 expo-cli 初始化的项目一样可以执行yarn web,这时会在本地8080端口运行一个服务,这时我们分别执行yarn ios 和 yarn android就能看到在ios模拟器和Android模拟器中显示和web端一模一样的页面,一次 react-native-web 的多端同构 Hello World 就成功实现了,当然这也意味着我们还可能编译成小程序,后续有机会一起探讨探讨!

此处的注意点:

  1. 代码能得以成功拷贝全靠梯子,当然也可以选择去网页下载;
  2. Android能得以成功运行,全靠给权限sudo 755 android/gradlew;
  3. React Native 入口文件需修改为 App.web,不然只有Web端才能读取App.web.js;
  4. 适当执行./gradlew clean重新yarn android等多年经验积累骚操作排除故障.

探究代码

关键的操作在于那行Copy代码的命令,那究竟上文中提到到下载了4的文件到底做了啥呢?Copy攻城狮心中也有一个大大的问号,Talk is cheap, show me the code,打开文件看看那些代码吧!

  • index.html

常见的单页面应用入口,像下面代码中的 div 我们称其为“根” DOM节点,因为其中的所有内容都将由React DOM进行管理。在当前案例中,我们只是设置一些基本样式以使主体div具有完整的高度和宽度:

 <html>
...
... <body> <div id =“ app-root”> </ div> </ body>
</ html>
  • index.web.js

使用index.web.js可以在Web和移动端之间区分开来,通过.web.js扩展名可以使该文件仅在Web上使用,其他一些可用的扩展如.native.js、.ios.js和.android.js适用于移动端。当然,如果您希望将本不同端的代码都保存在一个index.js文件中,则可以使用import { Platform } from 'react-native'来按照条件区分不同平台的代码。可以参考React Native官方文档中有关平台特定代码的更多信息。

index.web.js:
...
...
AppRegistry.runApplication(appName,{ initialProps:{},rootTag:document.getElementById('app-root'),
});

这与我们移动端的index.js非常相似,不过它还将您的应用程序挂载到根目录中index.html的div上。

  • webpack.config.js

webpack虽然是重点内容,但此处不过过多介绍,请前往官方文档阅读更加详细的内容,此案例中我们用到了三个插件:

  1. HtmlWebpackPlugin创建HTML;
  2. HotModuleReplacementPlugin用于热模块重装;
  3. DefinePlugin定义变量,例如__DEV__或NODE_ENV中react-native-web。
  • App.web.tsx

该文件是临时添加的文件,用于在使用React Native Web 同构之前验证我们的设置是否正常运行。最终,您可以删除此文件,因为App的入口js文件可以在移动端运行,也能在Web端运行。不过为了处理某些在Web上能运行而在移动端不能运行的业务,需要将代码抽离出来存放在`.web.js`为后缀的文件中。

后记

结合上述的简单案例,在后续实际业务中,我们可以逐步尝试同构业务到Web并逐步进行验证。

本文分享自华为云社区《React Native 项目 Web 端同构初探》,原文作者:胡琦。

点击关注,第一时间了解华为云新鲜技术~

技术实践丨React Native 项目 Web 端同构相关推荐

  1. 【腾讯Bugly干货分享】React Native项目实战总结

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/577e16a7640ad7b4682c64a7 "8小时内拼工作,8小 ...

  2. React native 项目进阶(redux, redux saga, redux logger)

    之前利用知乎日报的api写了react-native的一个入门项目,传送文章地址React Native 项目入门和源码地址RN入门项目源码,目前github上的代码已经在原文的基础上增加了新的功能, ...

  3. React Native 项目整合 CodePush 完全指南

    作者 | 钱凯 杏仁移动开发工程师,前嵌入式工程师,关注大前端技术新潮流. 本文使用的环境: React@16.3.1 React Native@0.55.4 react-native-code-pu ...

  4. java webpack web项目_官方出品,微信小程序和 Web 端同构解决方案——kbone

    介绍 最近在琢磨一些小程序开发和移动web开发,偶然间在Github上看到了这样一个项目--kbone,一个致力于微信小程序和 Web 端同构的解决方案.微信小程序的底层模型和 Web 端不同,我们想 ...

  5. React Native 项目常用第三方组件汇总

    React Native 项目常用第三方组件汇总 https://www.jianshu.com/p/d9cd9a868764?utm_campaign=maleskine&utm_conte ...

  6. vscode 连接夜神模拟器 运行 react native项目 (很简单的方法)

    前言:我这种方式不需要过多配置,只是需要先启动Android studio ,之后再启动vsCode 准备阶段:下载夜神模拟器 1. 开启夜神服务 进入到夜神安装的bin目录下,执行 nox_adb. ...

  7. 如何高效管理 React Native 项目中的图片资源

    本文为 Marno 原创,转载必须保留出处! 公众号[ Marno ],关注后回复 RN 加入交流群 React Native 优秀开源项目大全:http://www.marno.cn 前言 刚开始写 ...

  8. vue技术分享ppt_胡中南:Web端GIS技术新进展 | GTC专题论坛报告(视频+PPT+速记)

    点击图片上方蓝色字体"慧天地"即可订阅 文章转载自微信公众号GIS软件技术大会,版权归原作者及刊载媒体所有. 在GTC 2020『GIS基础软件新技术论坛』上,超图研究院副院长胡中 ...

  9. 【前端-React Native】移动端原生开发整合React Native Elements教程-安卓示例

    目录 一.移动开发和web开发的区别 二.什么是React Native? 三.如何实现安卓和IOS用一套代码开发 四.React Native开发实战 1. 安装Android studio 2. ...

最新文章

  1. etcd使用之ttl不准确问题
  2. vue中echarts 5.0版本以上不支持因为官方移除了地图数据和map文件夹
  3. CentOS 6 安装Hadoop 2.6 (四)运行简单例子
  4. jstorm 读取mysql_jstorm运维经验转载
  5. poj 1679 TheUniqueMST 最小生成树Kruskal(、Prim待做
  6. 二叉线索树的线索化以及遍历
  7. 计算机网络(北京理工大学出版社)课后习题答案
  8. 【行测】图形找规律类题目
  9. win7计算机扫描仪,win7系统怎么用打印机扫描仪功能|win7系统扫描仪功能的使用方法...
  10. 码农故事:一个辞职创业卖凉皮的程序员
  11. 模指数运算之python实现
  12. 关于网络小说均订的那些事:有些已成历史,有些在不断打破纪录
  13. 2019年个人成长计划
  14. 区块链技术应用场景之政务链
  15. 微软服务器上市时间,微软Office 2010全球发布会时间确定
  16. 自己动手用3D打印出你的个人数学科技馆
  17. Scene Management --- Culling
  18. 数据科学与计算机学院凌云,向凌云副教授
  19. 六大计算机应用领域,人工智能领域六大分类
  20. Vue结合element-ui实现导航菜单展开收缩小功能

热门文章

  1. Git 仓库中文件名大小写问题
  2. Bootstrap 弹出提示插件Popover 的选项
  3. 卡尔曼滤波原理(2)
  4. TensorFlow笔记(3) TensorBoard可视化
  5. mysql 更改一行_mysql怎么修改数据表里一行数据?
  6. java添加锁_java – 如何在这种情况下添加锁?
  7. cropper+pillow处理上传图片剪裁(一)
  8. 20165208 课下作业
  9. jsp内置对象的提交方式
  10. clientHeight、offsetHeight、scrollHeight问题