共计 3161 个字符,预计需要花费 8 分钟才能阅读完成。
如果你应用 react native 开发了 app,会不会想有一个站点呢。如果你想,那么 react-native-web 就有用武之地了。只有不是平台相干的组件根本都能够复用,包含 js 款式。更不用说内置的 accessibility。
react-native-web 比拟偏向于举荐 expo 的,更多的介绍是对于 create-react-app
生成的代码的。然而这篇文章是对于曾经能存在的 mobile 的我的项目而言的。这是一种更急广泛,或者更须要这篇文章的状况。
代码在这里
增加依赖
要是应用 react-native-web 首先要增加必须的依赖。首先跳转到我的项目的根目录
cd path-to-your-project
先把 react-native-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
如果你有前端的开发教训的话,看看咱们当初我的项目的构造你会发现少了很多。作为一个单页利用,单页都还没有呢。dev server 和打包的老大哥 webpack 也没有。这些咱们也都要一一加上。
index.html
<!DOCTYPE html>
<html>
<!-- 略 -->
<body>
<div id="app-root"></div>
</body>
</html>
这个就是单页利用的那个单页。是作为整个 app 的承载页。所有的 js 都运行在这个页面里。
webpack.config.js
// ...
const compileNodeModules = [// 增加须要编译的 react-native 包].map((moduleName) => path.resolve(appDirectory, `node_modules/${moduleName}`));
// ...
webpack
是打包工具。开发的时候跑 dev server,发生产的时候打生产包。这里须要制订 webpack 把依赖到的包都编译了。
如果你不这么做的话,大概率你会遇到这个么一个报错。比方你用了react-native-gesture-handler
。
ERROR in ./node_modules/react-native-gesture-handler
Module parse failed: Unexpected token
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
而后咱们也会增加所有须要编译的代码。比方 index.web.js
,App.web.tsx
。还有src 目录下的所有代码,以及上文提到的所有的库。
// ...
const babelLoaderConfiguration = {
test: /\.js$|tsx?$/,
// Add every directory that needs to be compiled by Babel during the build.
include: [path.resolve(__dirname, 'index.web.js'), <-- Entry to web project
path.resolve(__dirname, 'App.web.tsx'), // <-- or App.js
path.resolve(__dirname, 'src'), // <-- Main source folder
...compileNodeModules, // <-- Modules we compiles above
],
// ...
还有一个很重要的文件:index.web.js
这个文件是给上文说的 index.html 挂载 react-native-web 的组件的。就如同在 index.js 看到的要 AppRegistry.registerComponent
一样。在 web 开发中也须要注册组件,同时还要挂载组件。
index.web.js
import {AppRegistry} from 'react-native';
import {name as appName} from './app.json';
import App from './App';
if (module.hot) {module.hot.accept();
}
AppRegistry.registerComponent(appName, () => App); // 1
AppRegistry.runApplication(appName, { // 2
initialProps: {},
rootTag: document.getElementById('app-root'),
});
// 1. 和 index.js 一样,注册组件
// 2. 挂载组件。细节没看,预计是用来调用 react-dom 来实现的。
不同平台指定代码。比方这里的 index.web.js。就是特指给 web 平台执行的代码。在 ios 和 android 也能够别离指定在某个平台执行的代码。比方只在 ios 执行,能够命名为 SomeComp.ios.js。在 android 的就能够叫做 SomeComp.android.js。
另外须要增加一个App.web.tsx
//...
<TouchableOpacity
onPress={() => setCount(count + 1)}
style={styles.button}>
<Text>Click me!</Text>
</TouchableOpacity>
<WebSection title="web title">
<Text>Hello Web</Text>
</WebSection>
<Text>You clicked {count} times!</Text>
//...
显著能够看到解决点击的 TouchableOpacity
和显示文字的 Text
组件都能够失常应用。
复用代码
在 YouKnowApp/src/WebSection.tsx 这个文件是间接复用的 js/components/Section.tsx 这个文件。间接用会出问题。
Module parse failed: Unexpected token (11:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file
只有正文掉这一行就好了。
// import {Colors} from 'react-native/Libraries/NewAppScreen';
预计这行代码应用了 flow 导致的。
Flow 是 FB 开发的一个 js 的类型加强工具。当初用的曾经很少了,次要是 FB 本人的很多代码还蕴含了这部分。
解决的方法可能要查阅一下是否存在一个 webpack 的 loader 能够专门解决 flow 代码。
配置 Scripts
最初在 package.json 文件增加脚本执行的命令
"build": "rm -rf dist/ && webpack --mode=production --config webpack.config.js",
"web": "webpack serve --mode=development --config webpack.config.js"
运行
yarn web
查看 http://localhost:8080 就能够看到成果了。
完
后续遇到多平台代码共享的问题再持续更新。