编写一次,使用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.0yarn 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-webyarn 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.json package.json
app.json
app.json
App.test.js
App.test.js
├──App.js App.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-nativereact-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