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

Cannot load ReactWebChat with requireJS. #5406

Open
FDUS105301 opened this issue Jan 9, 2025 · 3 comments
Open

Cannot load ReactWebChat with requireJS. #5406

FDUS105301 opened this issue Jan 9, 2025 · 3 comments
Labels
Bot Services Required for internal Azure reporting. Do not delete. Do not change color. bug Indicates an unexpected problem or an unintended behavior. customer-reported Required for internal Azure reporting. Do not delete.

Comments

@FDUS105301
Copy link

FDUS105301 commented Jan 9, 2025

Is it an issue related to Adaptive Cards?

No

Is this an accessibility issue?

No

What version of Web Chat are you using?

Latest production

Which distribution are you using Web Chat from?

NPM

Which hosting environment does this issue primarily affect?

Web apps

Which browsers and platforms do the issue happened?

Browser: Chrome (latest), Browser: Edge (latest)

Which area does this issue affect?

Development experience

Which theme pack does this issue affect?

I did not test it on other theme packs

What is the public URL for the website?

No response

Please describe the bug

import ReactWebChat, { createDirectLine, createStore } from "botframework-webchat";

<ReactWebChat username={formData.current.name} activityMiddleware={middleWareHandle} directLine={directLineRef.current} styleOptions={{hideUploadButton:true}} onRenderActivity={() => { scrollToBottom(); }} />
this is how i am importing and using the component

This is my WebPack

const path = require('path');
const webpack = require('webpack');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  devtool: 'source-map', // Enables source maps
  mode: 'development',
  entry: './src/Components/chat-window/chat.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'chat.bundle.js',
    library: 'ChatComponent',
    libraryTarget: 'umd', //tried with amd as well, no luck
    globalObject: 'this',
    publicPath: 'https://your-cdn.net/react-widget/', // Replace with your CDN URL
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
        },
      },
      {
        test: /\.(png|jpe?g|gif|svg)$/,
        type: 'asset/resource',
        generator: {
          filename: 'images/[name][ext]', // Ensure a subdirectory for images
        },
      },
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          'css-loader',
          'sass-loader',
        ],
      },
    ],
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  externals: {
    react: 'react',
    'react-dom': 'reactDom',
    webchat: 'WebChat', //This is for the js bundle approach which will eb described below
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: 'chat.css',
    }),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('development'),
    }),
  ],
  optimization: {
    minimize: false, // Disable minification
  },
};

Issue 1

When i bundle my code with webpack, i try to use the said bundle on a magento environment which is fully dependent on requireJS. I have tried both, amd and umd targetLibs, with each target, botframework-webchat does not want to load. I get this error: uncaught error mismatched anonymous define() module.

Issue 2

Since NPM package doesnt work, i was able to use the js bundle directly and bind it to window. This works like a charm, since i can use window bound functions from the package as to fullfill my dependencies. However, when the bundled code updates a state, there is an issue where i get this error: **Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app
    See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.**

My assumption is that since the js bundle of the package comes with its own react instance, this causes the issue.

So basically I am not able to load the package via requiresJS due to incompatible bundling (since there is only 1 version of the bundle, its especially annoying) and If i try to use the js bundle in my react app directly, i cant since state updates break the code.

Please let me know if i am doing anything wrong.

Do you see any errors in console log?

1) uncaught error mismatched anonymous define() module


2) Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.

How to reproduce the issue?

Load bundled js code (preferably umd for requireJS in this case):

  (function () {
    if (typeof require !== 'undefined' && require.config) {
      require.config({
        paths: {
          jquery: 'link_to_jquery',
          react: 'https://unpkg.com/[email protected]/umd/react.production.min',
          reactDom: 'https://unpkg.com/[email protected]/umd/react-dom.production.min',
          chat: 'https://your-cdn.net/react-widget/chat.bundle',
        },
        shim: {
          jquery: {
            exports: '$',
          },
        },
      });
      console.log('RequireJS configuration has been set.');

      require(['react', 'reactDom', 'chat'], function (React, ReactDOM, ChatModule) {
        const ChatComponent = ChatModule.default; // Access the default export
        ReactDOM.render(
         React.createElement(ChatComponent),
         document.getElementById('root')
         );
      });
    } else {
      console.error('RequireJS is not loaded or configured.');
    }
  })();
</script>

Use bundle directly:

import React, { useState, useEffect, useRef } from "react"; function Chat() { const { ReactWebChat, createDirectLine, createStore } = window.WebChat; // Use global WebChat ... }

What do you expect?

Intended behavior should be:

  1. Module should be compatible with requireJS
  2. Like React, there should be multiple options for js bundles [target libs, versions etc...]

What actually happened?

Failed to load bundled code on requireJS
Unable to use js bundles in react environment because of prepackaged react instance already present in bundle causing hook errors.

Do you have any screenshots or recordings to repro the issue?

No response

Adaptive Card JSON

Additional context

No response

@FDUS105301 FDUS105301 added Bot Services Required for internal Azure reporting. Do not delete. Do not change color. bug Indicates an unexpected problem or an unintended behavior. customer-reported Required for internal Azure reporting. Do not delete. labels Jan 9, 2025
@OEvgeny
Copy link
Collaborator

OEvgeny commented Jan 10, 2025

I see the issue you're running into. Web Chat doesn't support RequireJS directly, but there's a workaround using globals to replace Web Chat's built-in React with your own version.

Since you're using RequireJS, here's how you can fix the React instance conflict:

require(['react', 'reactDom'], function (React, ReactDOM) {
    // Expose React globally first
    window.React = React;
    window.ReactDOM = ReactDOM;  // Only needed if using renderWebChat APIs

    // Now load Web Chat by adding a script tag
});

This way, Web Chat will use your application's React instance instead of its bundled one, which should resolve the hook errors you're seeing. Let me know if you need any clarification!

@FDUS105301
Copy link
Author

FDUS105301 commented Jan 11, 2025

@OEvgeny, thanks for youre response!

I see the issue you're running into. Web Chat doesn't support RequireJS directly, but there's a workaround using globals to replace Web Chat's built-in React with your own version.

Since you're using RequireJS, here's how you can fix the React instance conflict:

require(['react', 'reactDom'], function (React, ReactDOM) {
// Expose React globally first
window.React = React;
window.ReactDOM = ReactDOM; // Only needed if using renderWebChat APIs

// Now load Web Chat by adding a script tag

});

This way, Web Chat will use your application's React instance instead of its bundled one, which should resolve the hook errors you're seeing. Let me know if you need any clarification!

There is a problem with this. Since loading the script goes through requireJS, it doesnt work. My current workaround already in place is to set window.define = undefined; to load the script and then set define back to its original value. So The script has to be loaded as early as possible in the . My question is, why is there no support for requireJS given its "popularity"?

@OEvgeny
Copy link
Collaborator

OEvgeny commented Jan 11, 2025

Actually, RequireJS reached end-of-life in 2020 (see requirejs/requirejs#1816), which is why Web Chat doesn't include specific RequireJS support. However, you don't need to manipulate the window.define - that's a bit risky. Instead, you can simply load Web Chat using a script tag after setting up React:

require(['react', 'reactDom'], function (React, ReactDOM) {
    // Set up React globals
    window.React = React;
    window.ReactDOM = ReactDOM;

    // Load Web Chat via script tag
    const script = document.createElement('script');
    script.src = 'your-webchat-bundle-url.js';
    document.head.appendChild(script);

    // Or alternatively, you can add the script tag directly in your HTML after your require setup:
    // <script src="your-webchat-bundle-url.js"></script>
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bot Services Required for internal Azure reporting. Do not delete. Do not change color. bug Indicates an unexpected problem or an unintended behavior. customer-reported Required for internal Azure reporting. Do not delete.
Projects
None yet
Development

No branches or pull requests

2 participants