react-native-paper: App fails to compile with react-native-web

I’m trying to use react-native-paper in conjunction with react-native-web. React-native-web is an npm package which aliases react-native, and allows you to run react-native apps in the browser (ie: no simulator). It renders components as android, and it uses react-native v0.55.

Current behaviour

When I run the app without using react-native-paper, it runs fine. When I use react-native-paper however, I currently get an error message (see below) and the app fails to compile.

Expected behaviour

I expect for the app to run as a react-native-web app, with* react-native-paper* providing components. Below is the error message I receive when I run npm start.

Failed to compile
./node_modules/react-native-paper/src/index.js
SyntaxError: /media/binyamin/Seagate Expansion Drive/Documents/Coding/react-native/my-web-app/node_modules/react-native-paper/src/index.js: Unexpected token (4:12)

  2 | 
  3 | import * as Colors from './styles/colors';
> 4 | import type { Theme as _Theme } from './types';
    |             ^
  5 | 
  6 | export type Theme = _Theme;
  7 | 

Code sample

Github Repo: https://github.com/b3u/my-web-app Just run npm start to reproduce the issue

Screenshots (if applicable)

What have you tried

1. Search Google
2. Search existing issues
3. Create a custom theme
4. Opt out of using icons
5. Downgrade to v2.1.3

Your Environment

software version
ios or android n/a (the web app displays as android)
react-native react-native-web v0.9.8
react-native-paper v2.2.8
node v10.13
npm or yarn npm v6.4.1

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 45 (18 by maintainers)

Most upvoted comments

Also, do you think you can reference this issue on the readme so that others can get helped from it?

We’re planning to publish already transpiled code to NPM so the babel stuff won’t be necessary, but yea, we’ll add a guide to use with react-native-web soon.

@satya164 Hi!

I got the same error as @b3u, but in my case I used expo to create my base app to use react-native-web.

Is there any specific configuration to webpack from expo?

here is my babel.config.js

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
    env: {
      production: {
        plugins: ['react-native-paper/babel'],
      },
    },
  };
};

If you are using https://facebook.github.io/create-react-app. You can use https://github.com/timarney/react-app-rewired to config webpack without react-scripts eject.

// config-overrides.js
module.exports = function override(config, env) {
    config.module.rules.push({
        test: /\.js$/,
        exclude: /node_modules[/\\](?!react-native-paper|react-native-vector-icons|react-native-safe-area-view)/,
        use: {
          loader: "babel-loader",
          options: {
            // Disable reading babel configuration
            babelrc: false,
            configFile: false,

            // The configration for compilation
            presets: [
              ["@babel/preset-env", { useBuiltIns: "usage" }],
              "@babel/preset-react",
              "@babel/preset-flow"
            ],
            plugins: [
              "@babel/plugin-proposal-class-properties",
              "@babel/plugin-proposal-object-rest-spread"
            ]
          }
        }
      });

    return config;
  }

And try run your application.

I can describe how to get react-native-paper working in expo.

  1. expo init --yarn --template blank demo-app

cd demo-app

  1. yarn add react-native-web react-router-dom react-router-native react-app-polyfill react-art react-native-paper react-dom

yarn add -D react-scripts @babel/preset-flow @babel/plugin-proposal-class-properties

  1. code package.json and add scripts:

    “web”: “react-scripts start”, “build-web”: “react-scripts build”

– we’re going to be cheating and editing them in-place. A better practice is to copy node-modules/react-scripts/ config and scripts into your project folder, install their dependencies and get them working locally. But this is just a proof-of-concept (so … just be sure not to reinstall node_modules or react-scripts for now on)

– configure/add main:

“main”: “react-native-main.js”,

  1. code react-native-main.js saving:
import { KeepAwake, registerRootComponent } from 'expo'
import App from './src/App'

if (__DEV__) {
  KeepAwake.activate()
}

registerRootComponent(App)
  1. mkdir src public

  2. rm App.js

code src/App.js saving:

import React from 'react'
import { StyleSheet, View } from 'react-native'
import { Provider as PaperProvider } from 'react-native-paper'
import { Router, Switch, Route } from './routing'

import Home from './Controllers/Home'

export default class App extends React.Component {
  render () {
    return (
      <PaperProvider>
        <View style={styles.app}>
          <Router>
            <Route exact path="/" render={props => <Home {...props} />} />
          </Router>
        </View>
      </PaperProvider>
    )
  }
}

const styles = StyleSheet.create({
  app: {
    flex:1
  }
})
  1. mkdir src/Controllers && code src/Controllers/Home.js saving: (need to make something to demo Paper … this is essentially just the text example from the examples folder)
/* @flow */

import React from 'react'
import { View, StyleSheet, Platform } from 'react-native'
import {
  Caption,
  Headline,
  Paragraph,
  Subheading,
  Title,
  withTheme,
  type Theme,
} from 'react-native-paper'

type Props = {
  theme: Theme,
};

class TextExample extends React.Component<Props> {
  render() {
    const {
      theme: {
        colors: { background },
      },
    } = this.props
    return (
      <View style={[styles.container, { backgroundColor: background }]}>
        <Caption style={styles.text}>Home</Caption>
        <Paragraph style={styles.text}>This is the home component</Paragraph>
        <Subheading style={styles.text}>home component</Subheading>
        <Title style={styles.text}>Home</Title>
        <Headline style={styles.text}>Home on { Platform.OS }</Headline>
      </View>
    )
  }
}
const styles = StyleSheet.create({
  container: {
    padding: 16,
    flex: 1,
  },
  text: {
    marginVertical: 4,
  },
})

export default withTheme(TextExample)
  1. code public/index.html saving:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Third Party Demo</title>
</head>
<body>
    <div id="react-native-web-app"></div>
</body>
</html>
  1. code src/index.js saving:
import React from 'react'
import ReactDom from 'react-dom'

import App from './App'

ReactDom.render(<App />, document.getElementById('react-native-web-app'))
  1. code src/routing.native.js saving:

export { NativeRouter as Router, Switch, Route, Link } from ‘react-router-native’

code src/routing.web.js saving:

export { BrowserRouter as Router, Switch, Route, Link } from ‘react-router-dom’

  1. at this point, yarn iosshould work but yarn web gives the error reported here. We need to edit the react-scripts Webpack config node_modules/react-scripts/config/webpack.config.js:

– to the plugins of the section marked:

            // Process application JS with Babel.
            // The preset includes JSX, Flow, TypeScript, and some ESnext features.

(at about line 387) add this plugin:

                  [
                    "@babel/plugin-proposal-class-properties",
                    {
                      "loose": false
                    }
                  ]

after that section, create a new section:

            // Process paper specially
            {
              test: /\.js$/,
              exclude: /node_modules(?!\/react-native-paper|\/react-native-vector-icons)/,
              use: {
                loader: require.resolve('babel-loader'),
                options: {
                  babelrc: false,
                  configFile: false,
                  compact: false,
                  presets: [
                    '@babel/preset-env',
                    '@babel/preset-react',                
                    '@babel/preset-flow',
                  ],
                  cacheDirectory: true,
                  plugins: [     
                    [
                      "@babel/plugin-proposal-class-properties",
                      {
                        "loose": false
                      }
                    ],
                  ],
                  // Don't waste time on Gzipping the cache
                  cacheCompression: false,
    
                  // If an error happens in a package, it's possible to be
                  // because it was compiled. Thus, we don't want the browser
                  // debugger to show the original code. Instead, the code
                  // being evaluated would be much more helpful.
                  sourceMaps: false,
                },
              }
            },

When I run npm run build, I get the following error:

ERROR in ./src/index.js 30:4
Module parse failed: Unexpected token (30:4)
You may need an appropriate loader to handle this file type.
| export default function Main() {
|   return (
>     <PaperProvider theme={theme}>
|       <App />
|     </PaperProvider>