If you use react native to develop an app, would you want to have a site? If you want, then react-native-web is useful. As long as the components are not platform-related, they can basically be reused, including js styles. Not to mention the built-in accessibility.

react-native-web tends to recommend create-react-app , and more introduction is about the code generated by 06182094fb047b. But this article is for the already existing mobile projects. This is a situation that is more urgent and common, or needs this article more.

The code is here

Add dependency

If you use react-native-web, you must first add the necessary dependencies. First jump to the root directory of the project

cd path-to-your-project

First add react-native-web

yarn add react-native-web

Then dependent dependencies

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

If you have front-end development experience, look at the structure of our current project and you will find a lot less. As a single page application, there is no single page yet. The dev server and webpack, the big brother of packaging, also don't have it. We will also add these one by one.
index.html

<!DOCTYPE html>
<html>
  <!-- 略 -->
  <body>
    <div id="app-root"></div>
  </body>
</html>

This is the single page of the single page application. It serves as the hosting page for the entire app. All js runs on this page.

webpack.config.js

// ...
const compileNodeModules = [
  // 添加需要编译的react-native包
].map((moduleName) => path.resolve(appDirectory, `node_modules/${moduleName}`));
// ...

webpack is a packaging tool. Run the dev server during development, and print the production package during production. Here you need to make webpack to compile all dependent packages.

If you don't do this, there is a high probability that you will encounter this error. For example, you used 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

Then we will also add all the code that needs to be compiled. For example, index.web.js , App.web.tsx . There are also src directory, as well as all the libraries mentioned above.

// ...
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
  ],
// ...

There is another very important file: index.web.js

This file is to mount the react-native-web component to the index.html AppRegistry.registerComponent seen in index.js. In web development, you also need to register components and also mount components.
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 16182094fb06cf, register the component
// 2. Mount the component. I didn't see the details, it is estimated to be used to call react-dom to achieve.

不同平台指定代码。比如这里的index.web.js。
就是特指给web平台执行的代码。在ios和android也可以分别指定在某个平台执行的代码。
比如只在ios执行,可以命名为SomeComp.ios.js。在android的就可以叫做SomeComp.android.js。

Also need to add a 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>
//...

This clearly shows that treatment click TouchableOpacity and display text Text components can be used normally.

Reuse code

The YouKnowApp/src/WebSection.tsx file is the directly reused js/components/Section.tsx file. Direct use will cause problems.

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

Just comment out this line.

// import { Colors } from 'react-native/Libraries/NewAppScreen';

It is estimated that this line of code is caused by flow.

Flow是FB开发的一个js的类型增强工具。现在用的已经很少了,主要是FB自己的很多代码还包含了这部分。

The solution may be to check whether there is a webpack loader that can handle flow code specifically.

Configure Scripts

Finally, add the script execution command to the package.json

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

run

yarn web

Check http://localhost:8080 to see the effect.
image.png

over

We will continue to update if we encounter the problem of multi-platform code sharing in the future.


小红星闪啊闪
914 声望1.9k 粉丝

时不我待