编写一次,使用Create React(Native)App和react-native-web在任何地方运行
aka当工具存在时…组成它们!
编辑2018年1月:我已经用最新版本更新了本文(没有更多的beta依赖项!)。 感谢@KajiTetsushi的帮助! 🙂
编辑2018年2月:所有版本都与React v16.2.0保持同步。 (不再需要将React降级到16.0.0)
自从React Native的第一个版本发布以来,我一直希望建立一个可以在任何平台上运行的React代码库。
我喜欢使用Cordova和Web技术构建多平台应用程序,但是React Native现在凭借其本机性能提高了标准。
到目前为止,当您想要拥有Web和Native的统一代码库时,您必须弄乱构建系统(Webpack和React Native打包器),以使所有内容协同工作。
现在有了Create React Native App和Create React App,我们不必担心这一层的复杂性。
我将指导您完成一个可在任何地方运行的代码库的步骤!
你需要 :
- 最新版本的Node(当我写这篇文章时,它是8.6.0)
- 创建反应应用
首先,使用创建一个React应用程序:
create-react-app my-hybrid-app && cd my-hybrid-app
我们需要在项目中添加一些依赖项:
要安装这些软件包,可以使用 npm
或 yarn
。
npm install --save-dev babel-plugin-transform-object-rest-spread babel-plugin-transform-react-jsx-source babel-preset-expo jest-expo flow-bin react-native-scripts react-test-renderer@16.2.0
或yarn add --dev babel-plugin-transform-object-rest-spread babel-plugin-transform-react-jsx-source babel-preset-expo jest-expo flow-bin react-native-scripts react-test-renderer@16.2.0
然后我们添加了react-native,react-native-web和expo的软件包:
npm install --save expo@^25.0.0 react-native@0.52.0 react-native-web
或yarn add expo@^25.0.0 react-native@0.52.0 react-native-web
现在,让我们添加一些构建React Native应用程序所需的文件:
- .babelrc
{
"presets": ["babel-preset-expo"],
"env": {
"development": {
"plugins": ["transform-object-rest-spread", "transform-react-jsx-source"]
}
}
}
- .watchmanconfig
{}
- .flowconfig
在您的项目目录中创建一个.flowconfig文件,并在此处添加可用的流设置
- app.json
{
"expo": {
"sdkVersion": "25.0.0"
}
}
App.test.js:这是测试React Native应用程序的入口。
import React from 'react';
import App from './App';import renderer from 'react-test-renderer';
it('renders without crashing', () => {
const rendered = renderer.create().toJSON();
expect(rendered).toBeTruthy();
});
然后添加一个App.js文件,这将是我们的React Native应用程序入口点。
import React from 'react'
import HybridApp from './src/App'export default class NativeApp extends React.Component {
render() {
return
}
}
那时,您的项目应如下所示:
my-hybrid-project
├──
README.md
.babelrc
.babelrc
.flowconfig
.flowconfig
├──.gitignore.gitignore
.watchmanconfig
.watchmanconfig
├──package.jsonpackage.json
app.json
app.json
App.test.js
App.test.js
├──App.jsApp.js <-- entry point for CRNA (don't move/rename it!)
-CRNA的
│App.js <-- entry point for CRNA (don't move/rename it!)
│App.js <-- entry point for CRNA (don't move/rename it!)
└──src
│src
├──index.js
│index.js <- entry point for CRA (don't move/rename it)
-CRA的
│index.js <- entry point for CRA (don't move/rename it)
│index.js <- entry point for CRA (don't move/rename it)
└──
│... more source files
│
└──public
public
├──index.html
index.html
├──favicon.icon
favicon.icon
└──manifest.json
现在让我们对package.json文件进行一些更改,并添加一些有用的脚本
// These scripts are merely copied from the create-react-native-app package.json file
...
"main": "./node_modules/react-native-scripts/build/bin/crna-entry.js",
"scripts": {
"start-web": "react-scripts start",
"build-web": "react-scripts build",
"test-web": "react-scripts test --env=jsdom",
"eject-web": "react-scripts eject","start-native": "react-native-scripts start",
"eject-native": "react-native-scripts eject",
"android": "react-native-scripts android",
"ios": "react-native-scripts ios",
"test-native": "node node_modules/jest/bin/jest.js --watch","test": "npm run test-web && npm run test-native"
},
"jest": {
"preset": "jest-expo"
}
...
一切都在我们的项目中设置,让我们在两个不同的终端窗口中启动两个打包程序。
1号航站楼 :
npm run start-web
oryarn start-web
2号航站楼:
npm run ios
或yarn ios
我们需要编辑./src/App.js
并在其中添加一些平台无关的代码。
现在,您可以编写所有代码,就像编写一些React Native代码一样。
这里的技巧是,Create React App别名的webpack配置自动将react-native
为react-native-web
(请参阅此处的配置)。
一切都为我们处理!
import React, { Component } from 'react'
import { View, Text, StyleSheet } from 'react-native'export default class App extends Component {
render() {
return (
Welcome to React ⚛️
To get started, edit src/App.js and save to reload.
)
}
}const styles = StyleSheet.create({
app: {
flex: 1
},
appHeader: {
flex: 1,
backgroundColor: '#222',
padding: 20,
justifyContent: 'center',
alignItems: 'center'
},
appTitle: {
fontSize: 16,
color: 'white'
},
appIntro: {
flex: 2,
fontSize: 30,
textAlign: 'center'
}
})
您现在应该看到:
网络上的结果与手机上的结果并不完全相同。 这是因为需要调整#root
DOM元素的样式以匹配其移动副本:
为此,请打开./src/index.css
并添加
/* ... */
#root {
display: flex;
flex-direction: column;
min-height: 100vh;
max-height: 100vh;#root {
display: flex;
flex-direction: column;
min-height: 100vh;
max-height: 100vh;
}
和田田!
您已经构建了第一个在Web,iOS和Android上运行的通用React组件。
我在这里什么都没发明:我利用了Create React App,Create React Native App,react-native-web和Expo背后的团队所做的出色工作。
您应该检查这些项目并给予支持! 它们有助于使React开发成为每个人都可以访问的!
这是@ PureFazz提供的很棒的入门仓库,可以非常快速地开始使用此设置! 🚀
joefazz / react-native-web-starter
react-native-web-starter –开发Web和跨平台本机应用程序的起点。 建立在CRA之上,并…
github.com
对更多与平台无关的React感兴趣吗? 🙂
在我解释的地方查看这些答案:
- 如何共享路由代码
- 如何使用自定义字体
最初发布在 sparkyspace.com