Search code examples
react-nativewebpackreact-native-vector-icons

React Native Web error with react-native-vector-icons


I am making an app with react-native and react-native-web. I have tried to add react-native-vector-icons to the project follow this documentation and i got an error on the web build:

ERROR in ./node_modules/react-native-vector-icons/lib/create-icon-set.js 91:8
Module parse failed: Unexpected token (91:8)
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
| 
|       return (
>         <Text selectable={false} {...props}>
|           {glyph}
|           {children}
 @ ./node_modules/react-native-vector-icons/FontAwesome.js 6:0-50 9:16-29
 @ ./src/App.js 1:1549-1597
 @ ./index.web.js 1:261-281

Here is my webpack.config.js:

const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')

const appDirectory = path.resolve(__dirname, '../')

const babelLoaderConfiguration = {
  test: /\.(js)|(jsx)$/,
  include: [
    path.resolve(appDirectory, 'index.web.js'),
    path.resolve(appDirectory, 'src'),
    path.resolve(appDirectory, 'node_modules/react-native-uncompiled'),
  ],
  use: {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true,
      presets: ['module:metro-react-native-babel-preset'],
      plugins: [
        'react-native-web',
        [
          'module-resolver',
          {
            alias: {
              '^react-native$': 'react-native-web',
            },
          },
        ],
      ],
    },
  },
}

const HtmlWebpackPluginConfig = {
  filename: 'index.html',
  template: path.resolve(appDirectory, 'index.html'),
}

const copyWebpackPluginConfig = {
  patterns: [
    {
      from: path.resolve(appDirectory, 'assets/fonts/'),
      to: path.resolve(appDirectory, 'public/assets/fonts'),
      noErrorOnMissing: true,
    },
    {
      from: path.resolve(appDirectory, 'assets/images/'),
      to: path.resolve(appDirectory, 'public/assets/images'),
      noErrorOnMissing: true,
    },
  ],
}

const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: 'url-loader',
    options: {
      name: '[name].[ext]',
      esModule: false,
    },
  },
}

const iconFontLoaderConfiguration = {
  test: /\.ttf$/,
  loader: 'url-loader', // or directly file-loader
  include: path.resolve(appDirectory, 'node_modules/react-native-vector-icons'),
}

module.exports = {
  entry: [path.resolve(appDirectory, 'index.web.js')],

  output: {
    filename: 'bundle.[contenthash].web.js',
    path: path.resolve(appDirectory, 'public'),
  },

  module: {
    rules: [
      babelLoaderConfiguration,
      imageLoaderConfiguration,
      iconFontLoaderConfiguration,
    ],
  },

  devServer: {
    host: '0.0.0.0',
  },

  plugins: [
    new HtmlWebpackPlugin(HtmlWebpackPluginConfig),
    new CopyWebpackPlugin(copyWebpackPluginConfig),
  ],

  resolve: {
    alias: {
      'react-native$': 'react-native-web',
      '@api': path.resolve(appDirectory, 'src/api/'),
      '@entities': path.resolve(appDirectory, 'src/entities/'),
      '@utils': path.resolve(appDirectory, 'src/utils/'),
      '@components': path.resolve(appDirectory, 'src/components/'),
      '@theme': path.resolve(appDirectory, 'src/theme/'),
      '@constants': path.resolve(appDirectory, 'src/constants/'),
      '@screens': path.resolve(appDirectory, 'src/screens'),
    },

    extensions: ['.web.js', '.js', '.jsx'],
  },
}

I also have tried to change url-loader to file-loader and ttf-loader an i got the same error


Solution

  • I've just faced exactly the same trouble, I've solved by adding these two rules in the webpack.config.js file

    ...
    module: {
      rules: [
        ...
          {
            test: /\.js$/,
            exclude: /node_modules\/(?!(react-native-elements|react-native-vector-icons)\/).*/,
            loader: 'babel-loader'
          },
          {
            test: /\.ttf$/,
            loader: 'url-loader',
            include: path.resolve(__dirname, "node_modules/react-native-vector-icons")
          }
      ]
    }
    ...