callstack / repack

A Webpack-based toolkit to build your React Native application with full support of Webpack ecosystem.
https://re-pack.dev
MIT License
1.48k stars 107 forks source link

Cannot read property 'call' of undefined error with __webpack_require__ #350

Closed AkankshaJagdish closed 1 year ago

AkankshaJagdish commented 1 year ago

Ask your Question

I'm facing an issue with my release APK of a code splitting app. I have used the Async Chunks guide to create the app, and the Inline Assets modification to add images when creating the chunks. The chunks appear to be the right size. Yet I am facing an error.

I have checked my imports. They are all done in this template:

const chunkName = React.lazy(
  () => import(/* webpackChunkName: "chunkname" */ './chunkName.js')
);

            <Suspense fallback={<View />}>
              <ChunkComponent resetChunk={resetChunk} />
            </Suspense>

I'm using Ubuntu (WSL) to built the app. I soon will not have access to a Linux device so I must be able to build this using a Windows device with WSL.

I have installed NodeJs, Java, and Android SDK on the WSL and am using them to build.

How do I fix this?

Here is the error log:

2023-04-26 14:30:36.289 30952-31010 AndroidRuntime          com.quiz_app_codesplit_4             E  FATAL EXCEPTION: mqt_native_modules
                                                                                                    Process: com.quiz_app_codesplit_4, PID: 30952
                                                                                                    com.facebook.react.common.JavascriptException: TypeError: Cannot read property 'call' of undefined

                                                                                                    This error is located at:
                                                                                                        in Lazy
                                                                                                        in Suspense
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in ImageBackground
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in Home
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in App
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in AppContainer, js engine: hermes, stack:
                                                                                                    __webpack_require__@1:5872
                                                                                                    tryCallOne@53:15
                                                                                                    anonymous@139:26
                                                                                                    anonymous@1:242857
                                                                                                    _callTimer@1:241850
                                                                                                    _callReactNativeMicrotasksPass@1:242018
                                                                                                    callReactNativeMicrotasks@1:243940
                                                                                                    __callReactNativeMicrotasks@1:138053
                                                                                                    anonymous@1:137180
                                                                                                    __guard@1:137930
                                                                                                    flushedQueue@1:137091

My webpack config file has been modified to include inline assets:

import path from 'path';
import TerserPlugin from 'terser-webpack-plugin';
import * as Repack from '@callstack/repack';

/**
 * More documentation, installation, usage, motivation and differences with Metro is available at:
 * https://github.com/callstack/repack/blob/main/README.md
 *
 * The API documentation for the functions and plugins used in this file is available at:
 * https://re-pack.netlify.app/
 */

/**
 * Webpack configuration.
 * You can also export a static object or a function returning a Promise.
 *
 * @param env Environment options passed from either Webpack CLI or React Native CLI
 *            when running with `react-native start/bundle`.
 */
export default (env) => {
  const {
    mode = 'development',
    context = Repack.getDirname(import.meta.url),
    entry = './index.js',
    platform = process.env.PLATFORM,
    minimize = mode === 'production',
    devServer = undefined,
    bundleFilename = undefined,
    sourceMapFilename = undefined,
    assetsPath = undefined,
    reactNativePath = new URL('./node_modules/react-native', import.meta.url)
      .pathname,
  } = env;
  const dirname = Repack.getDirname(import.meta.url);

  if (!platform) {
    throw new Error('Missing platform');
  }

    /**
   * Using Module Federation might require disabling hmr.
   * Uncomment below to set `devServer.hmr` to `false`.
   *
   * Keep in mind that `devServer` object is not available
   * when running `webpack-bundle` command. Be sure
   * to check its value to avoid accessing undefined value,
   * otherwise an error might occur.
   */
  // if (devServer) {
  //   devServer.hmr = false;
  // }

  /**
   * Depending on your Babel configuration you might want to keep it.
   * If you don't use `env` in your Babel config, you can remove it.
   *
   * Keep in mind that if you remove it you should set `BABEL_ENV` or `NODE_ENV`
   * to `development` or `production`. Otherwise your production code might be compiled with
   * in development mode by Babel.
   */
  process.env.BABEL_ENV = mode;

  return {
    mode,
    /**
     * This should be always `false`, since the Source Map configuration is done
     * by `SourceMapDevToolPlugin`.
     */
    devtool: false,
    context,
    /**
     * `getInitializationEntries` will return necessary entries with setup and initialization code.
     * If you don't want to use Hot Module Replacement, set `hmr` option to `false`. By default,
     * HMR will be enabled in development mode.
     */
    entry: [
      ...Repack.getInitializationEntries(reactNativePath, {
        hmr: devServer && devServer.hmr,
      }),
      entry,
    ],
    resolve: {
      /**
       * `getResolveOptions` returns additional resolution configuration for React Native.
       * If it's removed, you won't be able to use `<file>.<platform>.<ext>` (eg: `file.ios.js`)
       * convention and some 3rd-party libraries that specify `react-native` field
       * in their `package.json` might not work correctly.
       */
      ...Repack.getResolveOptions(platform),

      /**
       * Uncomment this to ensure all `react-native*` imports will resolve to the same React Native
       * dependency. You might need it when using workspaces/monorepos or unconventional project
       * structure. For simple/typical project you won't need it.
       */
      // alias: {
      //   'react-native': reactNativePath,
      // },
    },
    /**
     * Configures output.
     * It's recommended to leave it as it is unless you know what you're doing.
     * By default Webpack will emit files into the directory specified under `path`. In order for the
     * React Native app use them when bundling the `.ipa`/`.apk`, they need to be copied over with
     * `Repack.OutputPlugin`, which is configured by default inside `Repack.RepackPlugin`.
     */
    output: {
      clean: true,
      hashFunction: 'xxhash64',
      path: path.join(dirname, 'build/generated', platform),
      filename: 'index.bundle',
      chunkFilename: '[name].chunk.bundle',
      publicPath: Repack.getPublicPath({ platform, devServer }),
    },
    /**
     * Configures optimization of the built bundle.
     */
    optimization: {
      /** Enables minification based on values passed from React Native CLI or from fallback. */
      minimize,
      /** Configure minimizer to process the bundle. */
      minimizer: [
        new TerserPlugin({
          test: /\.(js)?bundle(\?.*)?$/i,
          /**
           * Prevents emitting text file with comments, licenses etc.
           * If you want to gather in-file licenses, feel free to remove this line or configure it
           * differently.
           */
          extractComments: false,
          terserOptions: {
            format: {
              comments: false,
            },
          },
        }),
      ],
      chunkIds: 'named',
    },
    module: {
      /**
       * This rule will process all React Native related dependencies with Babel.
       * If you have a 3rd-party dependency that you need to transpile, you can add it to the
       * `include` list.
       *
       * You can also enable persistent caching with `cacheDirectory` - please refer to:
       * https://github.com/babel/babel-loader#options
       */
      rules: [
        {
          test: /\.[jt]sx?$/,
          include: [
            /node_modules(.*[/\\])+react/,
            /node_modules(.*[/\\])+@react-native/,
            /node_modules(.*[/\\])+@react-navigation/,
            /node_modules(.*[/\\])+@react-native-community/,
            /node_modules(.*[/\\])+@expo/,
            /node_modules(.*[/\\])+pretty-format/,
            /node_modules(.*[/\\])+metro/,
            /node_modules(.*[/\\])+abort-controller/,
            /node_modules(.*[/\\])+@callstack\/repack/,
          ],
          use: 'babel-loader',
        },
        /**
         * Here you can adjust loader that will process your files.
         *
         * You can also enable persistent caching with `cacheDirectory` - please refer to:
         * https://github.com/babel/babel-loader#options
         */
        {
          test: /\.[jt]sx?$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              /** Add React Refresh transform only when HMR is enabled. */
              plugins:
                devServer && devServer.hmr
                  ? ['module:react-refresh/babel']
                  : undefined,
            },
          },
        },
        /**
         * This loader handles all static assets (images, video, audio and others), so that you can
         * use (reference) them inside your application.
         *
         * If you wan to handle specific asset type manually, filter out the extension
         * from `ASSET_EXTENSIONS`, for example:
         * ```
         * Repack.ASSET_EXTENSIONS.filter((ext) => ext !== 'svg')
         * ```
         */
        {
          test: Repack.getAssetExtensionsRegExp(Repack.ASSET_EXTENSIONS),
          use: {
            loader: '@callstack/repack/assets-loader',
            options: {
              inline: true, // add the inline option to inline assets as data URIs
              platform,
              devServerEnabled: Boolean(devServer),
              /**
               * Defines which assets are scalable - which assets can have
               * scale suffixes: `@1x`, `@2x` and so on.
               * By default all images are scalable.
               */
              scalableAssetExtensions: Repack.SCALABLE_ASSETS,
            },
          },
        },
      ],
    },
    plugins: [
      /**
       * Configure other required and additional plugins to make the bundle
       * work in React Native and provide good development experience with
       * sensible defaults.
       *
       * `Repack.RepackPlugin` provides some degree of customization, but if you
       * need more control, you can replace `Repack.RepackPlugin` with plugins
       * from `Repack.plugins`.
       */
      new Repack.RepackPlugin({
        context,
        mode,
        platform,
        devServer,
        output: {
          bundleFilename,
          sourceMapFilename,
          assetsPath,
        },
      }),
    ],
  };
};

The app uses Firebase to host the chunks. The chunk sizes are about 50 MB - 90 MB. The Scriptmanager resolves the files as follows:

/**
 * @format
 */

// index.js
import { AppRegistry } from 'react-native';
import { ScriptManager, Script } from '@callstack/repack/client';
import AsyncStorage from '@react-native-async-storage/async-storage'; 
import App from './src/App';
import { name as appName } from './app.json';

import firebase from '@react-native-firebase/app';
import storage from '@react-native-firebase/storage'; // import storage module separately
// import { GOOGLE_SERVICES_JSON } from './android/app/google-services.json'; // import Firebase config object
const GOOGLE_SERVICES_JSON = require('./android/app/google-services.json'); // import Firebase config object

// Initialize the Firebase app
if (!firebase.apps.length) {
  firebase.initializeApp(GOOGLE_SERVICES_JSON);
}

ScriptManager.shared.setStorage(AsyncStorage);

// Add resolver to ScriptManager
ScriptManager.shared.addResolver(async (scriptId) => {  
  // In dev mode, resolve script location to local file
  if (__DEV__) {    
    const localFilePath = Script.getDevServerURL(`remotes/${scriptId}.chunk.bundle`);
    console.log('Resolved script URL:', localFilePath);
    return {
      url: localFilePath,
      cache: false,
    };
  }

  // In production mode, resolve script location to Firebase Cloud Storage URL
  const storageRef = storage().ref(`remotes/${scriptId}.chunk.bundle`);
  console.log('Resolved script URL:', storageRef);
  const url1 = await storageRef.getDownloadURL();

  return {
    url: Script.getRemoteURL(url1),
    cache: false,
  };
});

AppRegistry.registerComponent(appName, () => App);
AkankshaJagdish commented 1 year ago

Update: I cloned the repository to an Ubuntu device, and am receiving the same error after building the app on it.

2023-04-26 22:32:24.192 31988-32079 ReactNativeJS           com.quiz_app_codesplit_4             E  TypeError: Cannot read property 'call' of undefined

                                                                                                    This error is located at:
                                                                                                        in Lazy
                                                                                                        in Suspense
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in ImageBackground
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in Home
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in App
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in AppContainer, js engine: hermes

2023-04-26 22:32:24.215 31988-32080 AndroidRuntime          com.quiz_app_codesplit_4             E  FATAL EXCEPTION: mqt_native_modules
                                                                                                    Process: com.quiz_app_codesplit_4, PID: 31988
                                                                                                    com.facebook.react.common.JavascriptException: TypeError: Cannot read property 'call' of undefined

                                                                                                    This error is located at:
                                                                                                        in Lazy
                                                                                                        in Suspense
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in ImageBackground
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in Home
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in App
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in RCTView
                                                                                                        in Unknown
                                                                                                        in AppContainer, js engine: hermes, stack:
                                                                                                    __webpack_require__@1:5872
                                                                                                    tryCallOne@53:15
                                                                                                    anonymous@139:26
                                                                                                    anonymous@1:242857
                                                                                                    _callTimer@1:241850
                                                                                                    _callReactNativeMicrotasksPass@1:242018
                                                                                                    callReactNativeMicrotasks@1:243940
                                                                                                    __callReactNativeMicrotasks@1:138053
                                                                                                    anonymous@1:137180
                                                                                                    __guard@1:137930
                                                                                                    flushedQueue@1:137091

                                                                                                        at com.facebook.react.modules.core.ExceptionsManagerModule.reportException(ExceptionsManagerModule.java:72)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
                                                                                                        at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:188)
                                                                                                        at com.facebook.jni.NativeRunnable.run(Native Method)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:942)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:99)
                                                                                                        at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
                                                                                                        at android.os.Looper.loopOnce(Looper.java:226)
                                                                                                        at android.os.Looper.loop(Looper.java:313)
                                                                                                        at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:228)
                                                                                                        at java.lang.Thread.run(Thread.java:1012)
2023-04-26 22:32:24.267 31988-32080 Process                 com.quiz_app_codesplit_4             I  Sending signal. PID: 31988 SIG: 9

Please help fix this issue. I really need Inline Assets to work.

RafikiTiki commented 1 year ago

I suggest using the Remote Assets released in the 3.2.0 version of Repack, especially in such asset-heavy apps. Encoding assets with base64 and inlining them into the bundles should never be used in cases where Remote Assets can do the job. Historically inline assets were the only built-in solution but right now, after releasing full support for the Remote Assets, it should be treated as a default solution.

Please try refactoring your code to use Remote Assets and see if that'll help. It will cut the bundle sizes significantly, and I get a feeling that the bundles size might be a problem. I've never worked with a JS bundle over 25MB in size.

However, if it doesn't solve your problem – please share a minimal reproduction repository so I can review the configuration. It'd be very helpful if you could create a demo project in the Firebase and add me there so I can verify how things are wired up on that end.

jbroma commented 1 year ago

Closing as reproduction wasn't provided and it's impossible to tell what the cause was. If the problem persists, please open a new issue.

pratt3351 commented 8 months ago

i'm expierence this issue when remote chunk changed that i removed some components.

any help..?