Search code examples
react-nativeexporeact-native-webreact-native-google-mobile-ads

react-native-google-mobile-ads + expo + web


I'm using expo + web. For the mobile ads I wantnd to use react-native-google-mobile-ads + conditional loading based on platform.

  if (Platform.OS !== 'web') {
    FFirstResultAdComponent = require("components/movies/result/first-result-ad-component").FirstResultAdComponent;
  }

The problem is that the library is still loaded by webpack for web build what leads to some issues while loading and prevent page from loading. What would be the best option to avoid this issues, exclude component + library from webpack? Or force to use cjs?

Json.js:74 Uncaught Error: Module parse failed: Unexpected token (7:16)
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
|      * in that '+' and '/' are replaced with '-' and '_'.
|      */
>     static DICT = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|     static REVERSE_DICT = new Map([
|         ['A', 0], ['B', 1], ['C', 2], ['D', 3], ['E', 4], ['F', 5],
    at ./node_modules/@iabtcf/core/lib/mjs/encoder/Base64Url.js (Json.js:74:1)
    at __webpack_require__ (bootstrap:789:1)
    at fn (bootstrap:100:1)
    at ./node_modules/@iabtcf/core/lib/mjs/encoder/index.js (index.js:1:1)
    at __webpack_require__ (bootstrap:789:1)
    at fn (bootstrap:100:1)
    at ./node_modules/@iabtcf/core/lib/mjs/index.js (index.js:1:1)
    at __webpack_require__ (bootstrap:789:1)
    at fn (bootstrap:100:1)
    at ./node_modules/react-native-google-mobile-ads/lib/module/AdsConsent.js (AdEventType.ts:18:1)
    at __webpack_require__ (bootstrap:789:1)
    at fn (bootstrap:100:1)
    at ./node_modules/react-native-google-mobile-ads/lib/module/index.js (index.ts:18:1)
    at __webpack_require__ (bootstrap:789:1)
    at fn (bootstrap:100:1)
    at ./App.tsx (bootstrap:856:1)
    at __webpack_require__ (bootstrap:789:1)
    at fn (bootstrap:100:1)
    at ./index.js (i18n.ts:10:1)
    at __webpack_require__ (bootstrap:789:1)
    at fn (bootstrap:100:1)
    at 1 (trpc-provider.tsx:35:1)
    at __webpack_require__ (bootstrap:789:1)
    at bootstrap:856:1
    at bootstrap:856:1
./node_modules/@iabtcf/core/lib/mjs/encoder/Base64Url.js @ Json.js:74
__webpack_require__ @ bootstrap:789
fn @ bootstrap:100
./node_modules/@iabtcf/core/lib/mjs/encoder/index.js @ index.js:1
__webpack_require__ @ bootstrap:789
fn @ bootstrap:100
./node_modules/@iabtcf/core/lib/mjs/index.js @ index.js:1
__webpack_require__ @ bootstrap:789
fn @ bootstrap:100
./node_modules/react-native-google-mobile-ads/lib/module/AdsConsent.js @ AdEventType.ts:18
__webpack_require__ @ bootstrap:789
fn @ bootstrap:100
./node_modules/react-native-google-mobile-ads/lib/module/index.js @ index.ts:18
__webpack_require__ @ bootstrap:789
fn @ bootstrap:100
./App.tsx @ bootstrap:856
__webpack_require__ @ bootstrap:789
fn @ bootstrap:100
./index.js @ i18n.ts:10
__webpack_require__ @ bootstrap:789
fn @ bootstrap:100
1 @ trpc-provider.tsx:35
__webpack_require__ @ bootstrap:789
(anonymous) @ bootstrap:856
(anonymous) @ bootstrap:856
VM1051:2 Uncaught ReferenceError: process is not defined
    at 4043 (<anonymous>:2:13168)
    at r (<anonymous>:2:306599)
    at 8048 (<anonymous>:2:9496)
    at r (<anonymous>:2:306599)
    at 8641 (<anonymous>:2:1379)
    at r (<anonymous>:2:306599)
    at <anonymous>:2:315627
    at <anonymous>:2:324225
    at <anonymous>:2:324229
    at e.onload (index.js:1:1)
4043 @ VM1051:2
r @ VM1051:2
8048 @ VM1051:2
r @ VM1051:2
8641 @ VM1051:2
r @ VM1051:2
(anonymous) @ VM1051:2
(anonymous) @ VM1051:2
(anonymous) @ VM1051:2
e.onload @ index.js:1
be @ index.js:1
de @ index.js:1
handleErrors @ webpackHotDevClient.js:169
./node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage @ webpackHotDevClient.js:213
load (async)
be @ index.js:1
de @ index.js:1
handleErrors @ webpackHotDevClient.js:169
./node_modules/react-dev-utils/webpackHotDevClient.js.connection.onmessage @ webpackHotDevClient.js:213
index.js:1 ./node_modules/@iabtcf/core/lib/mjs/model/PurposeRestrictionVector.js 10:14
Module parse failed: Unexpected token (10:14)
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
|      * bit length; it can be set and got from here
|      */
>     bitLength = 0;
|     /**
|      * a map indexed by a string which will be a 'hash' of the purpose and

webpack.config.js

const createExpoWebpackConfigAsync = require('@expo/webpack-config');
const path = require('path')

module.exports = async function (env, argv) {
    const config = await createExpoWebpackConfigAsync({
            ...env,
            babel: {
                dangerouslyAddModulePathsToTranspile: ["@trpc/react-query",
                    "@trpc/client", "@tanstack/react-query"],
            },
        },
        argv
    );
    config.module.rules.push(
        {
            test: /.mjs$/,
            include: /node_modules/,
            use: {
                loader: 'babel-loader',
                options: {
                    presets: [
                        [
                            "@babel/preset-env",
                            {
                                loose: false,
                            }
                        ]
                    ],
                    plugins: ['@babel/plugin-proposal-class-properties',
                        "@babel/plugin-proposal-private-property-in-object",
                        "@babel/plugin-proposal-optional-chaining"]
                }
            }
        });

    config.module.rules.push({
        test: /\.mjs$/,
        include: /node_modules/,
        type: "javascript/auto"
    });

    return config;
};

package.json

{
  "version": "1.0.0",
  "scripts": {
    "start": "expo start --dev-client",
  },
  "dependencies": {
    "@babel/plugin-proposal-export-namespace-from": "^7.18.9",
    "@babel/plugin-proposal-optional-chaining": "^7.18.9",
    "@babel/plugin-proposal-private-methods": "^7.18.6",
    "@babel/preset-env": "^7.20.2",
    "@expo/html-elements": "^0.2.2",
    "@expo/vector-icons": "^13.0.0",
    "@expo/webpack-config": "^0.17.3",
    "@hapi/iron": "^7.0.0",
    "@iabtcf/core": "^1.5.5",
    "@prisma/client": "^4.6.1",
    "@react-navigation/bottom-tabs": "^6.4.3",
    "@react-navigation/native": "^6.0.14",
    "@react-navigation/native-stack": "^6.9.2",
    "@react-navigation/stack": "^6.3.5",
    "@rneui/base": "^4.0.0-rc.7",
    "@rneui/themed": "^4.0.0-rc.7",
    "@tanstack/react-query": "^4.3.8",
    "@trpc/client": "^10.4.2",
    "@trpc/react-query": "^10.4.2",
    "@trpc/server": "^10.4.2",
    "@types/react": "~18.0.24",
    "@types/react-native": "~0.70.6",
    "babel-loader": "^8.3.0",
    "babel-plugin-jest-hoist": "^29.2.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-expo": "^9.2.2",
    "cookie": "^0.5.0",
    "cors": "^2.8.5",
    "expo": "~47.0.8",
    "expo-asset": "~8.6.2",
    "expo-auth-session": "~3.7.3",
    "expo-blur": "~12.0.1",
    "expo-build-properties": "~0.4.1",
    "expo-dev-client": "~2.0.1",
    "expo-localization": "~14.0.0",
    "expo-random": "~13.0.0",
    "expo-secure-store": "~12.0.0",
    "expo-splash-screen": "~0.17.5",
    "expo-status-bar": "~1.4.2",
    "expo-updates": "~0.15.6",
    "i18n-js": "^4.2.0",
    "install": "^0.13.0",
    "iron-session": "^6.3.1",
    "next": "^13.0.4",
    "next-compose-plugins": "^2.2.1",
    "next-connect": "^0.13.0",
    "next-fonts": "^1.5.1",
    "next-images": "^1.8.4",
    "next-transpile-modules": "^10.0.0",
    "nextjs-cors": "^2.1.2",
    "npm": "^9.1.3",
    "react": "18.1.0",
    "react-dev-tools": "^0.0.1",
    "react-dom": "18.1.0",
    "react-native": "0.70.5",
    "react-native-elements": "^4.0.0-beta.0",
    "react-native-fbsdk-next": "^11.1.0",
    "react-native-gesture-handler": "~2.8.0",
    "react-native-google-mobile-ads": "^8.2.2",
    "react-native-reanimated": "~2.12.0",
    "react-native-safe-area-context": "^4.4.1",
    "react-native-screens": "~3.18.0",
    "react-native-vector-icons": "^9.2.0",
    "react-native-web": "~0.18.9",
    "rimraf": "^3.0.2",
    "typescript": "^4.6.3",
    "zod": "^3.19.1"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9",
    "@expo/next-adapter": "^4.0.13",
    "babel-plugin-module-resolver": "^4.1.0",
    "prisma": "^4.6.1"
  },
  "prisma": {
    "schema": "schema.prisma",
    "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
  },
  "private": true
}

Solution

  • The correct solution is simple like a harm, just create wrappers for components and libraries. the first one with .tsx file extensions, that will be used for mobiles and only this one should point to react-native-google-mobile-ads and second one .web.tsx that could be completely blank, the only important thing is that he cannot have any references to react-native-google-mobile-ads and then webpack will do the job.