Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Property 'HMRClient' doesn't exist #501

Closed
mikeFromUDig opened this issue Feb 12, 2024 · 5 comments · Fixed by #556
Closed

Property 'HMRClient' doesn't exist #501

mikeFromUDig opened this issue Feb 12, 2024 · 5 comments · Fixed by #556
Labels
area:repack The issue is about logic/code inside of Re.Pack. area:windows Issues happening on Windows status:waiting-for-response Waiting for a response or clarification from the issue creator type:bug A bug report.

Comments

@mikeFromUDig
Copy link

Environment

  • Windows 11
  • "react": "18.2.0",
  • "react-native": "0.73.4"
  • targeting Android platform
  • "@callstack/repack": "^3.7.0",
  • "webpack": "^5.90.1"
  • "terser-webpack-plugin": "^5.3.10",

Description

Running into this issue on my windows local environment. Any help would be appreciated

Run steps:

  • run react-native webpack-start --host 127.0.0.1 --webpackConfig ./webpack.config.mjs in it's own terminal
  • run react-native run-android --no-packager in it's own terminal

App installs and presents following error on the emulated device
image

Reproducible Demo

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

/**

/**

  • 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.resolve(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-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: {
          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,
    },
  }),
],

};
};
`

@vinhmdev
Copy link

Sorry, but I resolved it by disabling HMR -_-,

In the ‘webpack.config.mjs’ file, replace:
hmr: devServer && devServer.hmr, -> hmr: false

@jbroma jbroma added status:new New issue, not reviewed by the team yet. type:bug A bug report. area:repack The issue is about logic/code inside of Re.Pack. area:windows Issues happening on Windows labels Feb 29, 2024
@jbroma
Copy link
Member

jbroma commented Feb 29, 2024

hi @mikeFromUDig

I don't have access to a Windows machine atm, but I have an idea what might be happening, can you try doing the following:

In webpack.config please replace

entry: [
  ...Repack.getInitializationEntries(reactNativePath, {
    hmr: devServer && devServer.hmr,
  }),
  entry,
],

with

entry: [
  ...Repack.getInitializationEntries(reactNativePath, {
    hmr: false,
  }),
  path.resolve('@callstack/repack/modules/WebpackHMRClient.js'),
  entry,
],

Please see if that works. The path to WebpackHMRClient might need some adjusting though.

@jbroma jbroma added status:waiting-for-response Waiting for a response or clarification from the issue creator and removed status:new New issue, not reviewed by the team yet. labels Feb 29, 2024
@peterbd
Copy link

peterbd commented Mar 14, 2024

hi @mikeFromUDig

I don't have access to a Windows machine atm, but I have an idea what might be happening, can you try doing the following:

In webpack.config please replace

entry: [
  ...Repack.getInitializationEntries(reactNativePath, {
    hmr: devServer && devServer.hmr,
  }),
  entry,
],

with

entry: [
  ...Repack.getInitializationEntries(reactNativePath, {
    hmr: false,
  }),
  path.resolve('@callstack/repack/modules/WebpackHMRClient.js'),
  entry,
],

Please see if that works. The path to WebpackHMRClient might need some adjusting though.

this doesn't work for me

Copy link

This issue has been marked as stale because it has been inactive for 30 days. Please update this issue or it will be automatically closed in 14 days.

@jbroma
Copy link
Member

jbroma commented Apr 16, 2024

@mikeFromUDig @vinhmdev @peterbd found the root issue.

to resolve the error in question please adjust the path of @callstack/repack inside of module.rules in webpack.config.mjs like this:

diff --git a/templates/webpack.config.mjs b/templates/webpack.config.mjs
index 18313be..e702a00 100644
--- a/templates/webpack.config.mjs
+++ b/templates/webpack.config.mjs
@@ -159,7 +159,7 @@ export default (env) => {
             /node_modules(.*[/\\])+pretty-format/,
             /node_modules(.*[/\\])+metro/,
             /node_modules(.*[/\\])+abort-controller/,
-            /node_modules(.*[/\\])+@callstack\/repack/,
+            /node_modules(.*[/\\])+@callstack[/\\]repack/,
           ],
           use: 'babel-loader',
         },

@jbroma jbroma removed the Stale label Apr 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:repack The issue is about logic/code inside of Re.Pack. area:windows Issues happening on Windows status:waiting-for-response Waiting for a response or clarification from the issue creator type:bug A bug report.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants