If you develop an app using React Native, you might want to have a site. If you want, then the React-native Web comes in handy. Almost anything that is not platform specific can be reused, including JS styles. Not to mention built-in accessibility.

The React-Native Web tends to recommend Expo, with more introductions to create-React-app generated code. But this article is for mobile projects that already exist. This is a situation that is more urgent, more common, or more in need of this article.

Here’s the code

Add the dependent

To use the React-native Web, you must first add the necessary dependencies. First jump to the root directory of the project

cd path-to-your-project
Copy the code

So let’s add the React-native Web

yarn add react-native-web
Copy the code

And then related 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
Copy the code

If you have experience with front-end development, look at the structure of our projects now and you will see that there is much less. As a one-page app, we don’t even have one page yet. Neither does Dev Server or packaged big brother Webpack. We’re going to add all of that. ** index.html **

<! DOCTYPEhtml>
<html>
  <! -- -- -- > slightly
  <body>
    <div id="app-root"></div>
  </body>
</html>
Copy the code

This is the single page of the single page application. Is the carrier page for the entire app. All js runs in this page.

** webpack.config.js **

// ...
const compileNodeModules = [
  // Add the react-native package that needs to be compiled
].map((moduleName) = > path.resolve(appDirectory, `node_modules/${moduleName}`));
// ...
Copy the code

Webpack is a packaging tool. Dev Server in development, production package in production. Here we need to specify that webpack compiles all the packages that depend on it.

If you don’t, chances are you’ll get an error. Let’s say you use react-native gear-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
Copy the code

Then we’ll also add all the code that needs to be compiled. Such as index.web.js, app.web. TSX. All the code in the SRC directory, and 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 ], // ...Copy the code

There is another important file: index.web.js

This file is used to mount the react-Native Web component to index.html above. As in the index. The js. See to AppRegistry registerComponent. Components also need to be registered and mounted in Web development. 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')});Copy the code

As with index.js, register the component // 2. Mount the component. React-dom is used to implement the react-dom function.

Different platform specified code. Such as index.web.js here. Code specifically for web platform execution. On ios and Android, you can also specify code to execute on a particular platform. For example, if it runs only on ios, you can name it somecomp.ios.js. On Android you can call it somecomp.android.js.Copy the code

You also need to add an 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>
/ /...
Copy the code

You can clearly see that the TouchableOpacity component that handles clicks and the Text component that displays Text are working fine.

Reuse code

In YouKnowApp/SRC/WebSection TSX this file is direct reuse of js/components/Section. The TSX this file. Using it directly can 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
Copy the code

Just comment out this line.

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

It is estimated that this line of code uses flow.

Flow is a JS type enhancement tool developed by FB. Now it is rarely used, mainly because many of FB's own codes also contain this part.Copy the code

A solution might be to see if there is a Webpack loader that can handle flow code.

The configuration Scripts

Finally, add the commands executed by the script to the package.json file

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

run

yarn web
Copy the code

Check out http://localhost:8080 to see the results.

After the

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