'Webpack babel-loader issue (react native web app)

Getting the following error when running on terminal:

"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"

Error line:

|   render() {
|     return (
>       <View style={styles.container}>
|         <Text style={styles.welcome}>
|           Welcome to React Native!

Here is my config file:

// web/webpack.config.js

const path = require('path');
const webpack = require('webpack');

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

// This is needed for webpack to compile JavaScript.
// Many OSS React Native packages are not compiled to ES5 before being
// published. If you depend on uncompiled packages they may cause webpack build
// errors. To fix this webpack can be configured to compile to the necessary
// `node_module`.
const babelLoaderConfiguration = {
  test: /\.js$/,
  //test: /\.txt$/,
  // Add every directory that needs to be compiled by Babel during the build.
  include: [
    path.resolve(appDirectory, 'index.web.js'),
    path.resolve(appDirectory, 'src'),
    path.resolve(appDirectory, 'node_modules/react-native-uncompiled')
  ],
  exclude: /node_modules/,
  use: {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true,
      // The 'metro-react-native-babel-preset' preset is recommended to match React Native's packager
      // presets: ['module:metro-react-native-babel-preset'],
      presets: [
        '@babel/preset-env',
        'module:metro-react-native-babel-preset'
        //['@babel/preset-env', { targets: "defaults" }],
        // 'react-native'
        // '@babel/preset-react',
      ],
      // Re-write paths to import only the modules needed by the app
      plugins: ['react-native-web']
    }
  }
};

// This is needed for webpack to import static images in JavaScript files.
const imageLoaderConfiguration = {
  test: /\.(gif|jpe?g|png|svg)$/,
  use: {
    loader: 'url-loader',
    options: {
      name: '[name].[ext]',
      esModule: false,
    }
  }
};

module.exports = {
  entry: [
    // load any web API polyfills
    // path.resolve(appDirectory, 'polyfills-web.js'),
    // your web-specific entry file
    path.resolve(appDirectory, 'index.web.js')
  ],

  // configures where the build ends up
  output: {
    filename: 'bundle.web.js',
    path: path.resolve(appDirectory, 'dist')
  },

  // ...the rest of your config

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

  resolve: {
    // This will only alias the exact import "react-native"
    alias: {
      'react-native$': 'react-native-web'
    },
    // If you're working on a multi-platform React Native app, web-specific
    // module implementations should be written in files using the extension
    // `.web.js`.
    extensions: [ '.web.js', '.js' ]
  }
}

package.json

{
  "name": "DTApp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "start": "react-native start",
    "test": "jest",
    "lint": "eslint ."
  },
  "dependencies": {
    "@react-native-community/async-storage": "^1.9.0",
    "@react-native-community/masked-view": "^0.1.10",
    "@react-native-community/netinfo": "^5.9.9",
    "@react-navigation/bottom-tabs": "^5.2.6",
    "@react-navigation/drawer": "^5.4.1",
    "@react-navigation/material-top-tabs": "^5.1.8",
    "@react-navigation/native": "^5.7.4",
    "@react-navigation/stack": "^5.12.6",
    "babel-jest": "^24.9.0",
    "i18next": "^21.5.4",
    "lodash.memoize": "^4.1.2",
    "metro-react-native-babel-preset": "^0.58.0",
    "moment": "^2.24.0",
    "npm": "^6.14.4",
    "number-to-locale-string-polyfill": "^1.0.9",
    "omise-react-native": "^0.1.0",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-i18next": "^11.14.3",
    "react-native": "0.62.2",
    "react-native-calendars": "^1.265.0",
    "react-native-chart-kit": "^6.7.0",
    "react-native-country-picker-modal": "^1.10.0",
    "react-native-date-picker": "^4.1.2",
    "react-native-device-info": "^7.1.0",
    "react-native-document-picker": "^3.5.3",
    "react-native-fbsdk": "^3.0.0",
    "react-native-geocoding": "^0.4.0",
    "react-native-geolocation-service": "^5.0.0",
    "react-native-gesture-handler": "^1.8.0",
    "react-native-google-places-autocomplete": "^1.7.1",
    "react-native-image-crop-picker": "^0.28.0",
    "react-native-image-zoom-viewer": "^3.0.1",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-linear-gradient": "^2.5.6",
    "react-native-localize": "^1.4.1",
    "react-native-maps": "0.27.1",
    "react-native-modal": "^11.5.6",
    "react-native-modalize": "^2.0.6",
    "react-native-onesignal": "^3.8.1",
    "react-native-picker-select": "^7.0.0",
    "react-native-popup-menu": "^0.15.7",
    "react-native-progress": "^5.0.0",
    "react-native-ratings": "^7.3.0",
    "react-native-reanimated": "^1.13.1",
    "react-native-root-toast": "^3.2.1",
    "react-native-safe-area-context": "^0.7.3",
    "react-native-screens": "^2.11.0",
    "react-native-share": "^3.7.1",
    "react-native-svg": "^12.1.0",
    "react-native-swiper": "^1.6.0-rc.3",
    "react-native-tab-view": "^2.14.0",
    "react-native-vector-icons": "^6.6.0",
    "react-native-view-shot": "^3.1.2",
    "react-native-web": "^0.17.5",
    "react-redux": "^7.2.0",
    "reanimated-bottom-sheet": "^1.0.0-alpha.19",
    "redux": "^4.0.5",
    "redux-thunk": "^2.3.0"
  },
  "devDependencies": {
    "@babel/core": "^7.16.5",
    "@babel/preset-env": "^7.16.5",
    "@babel/runtime": "^7.16.5",
    "@react-native-community/eslint-config": "^0.0.5",
    "babel-loader": "^8.2.3",
    "babel-plugin-react-native-web": "^0.17.5",
    "eslint": "^6.5.1",
    "jest": "^24.9.0",
    "jetifier": "^1.6.6",
    "react-test-renderer": "16.11.0",
    "url-loader": "^4.1.1",
    "webpack": "^5.65.0",
    "webpack-cli": "^4.9.1",
    "webpack-dev-server": "^4.6.0"
  },
  "jest": {
    "preset": "react-native"
  }
}

Been stuck for hours now. Any help appreciated.



Solution 1:[1]

I believe I just encountered the same issue and it ended up being a syntax change between webpack 4 and 5. All the docs/examples show the include and exclude syntax like you have, but it seems to have changed. I am using the exclude syntax like so:

exclude: [
  {
    and: [path.resolve(appDirectory, 'node_modules')],
    not: [
      path.resolve(appDirectory, 'node_modules/react-native-uncompiled'),
      path.resolve(appDirectory, 'node_modules/react-native-reanimated'),
    ],
  },
],

"and" is exclude and "not" is include.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mike H