Archived

This forum has been archived. Please start a new discussion on GitHub.

React app -- Ice.initialize() is not a function

Hi folks,
Trying to create a React client app in javascript which uses Ice to communicate with an Ice server app (python). I keep hitting an error like this one when I try to initialize my communicator:

Unhandled Rejection (TypeError): ice_lib_es5_Ice__WEBPACK_IMPORTED_MODULE_3___default.a.initialize is not a function
App.onConnect

  18 | 
  19 |    if (this.communicator === null)
  20 |    {


  21 |      this.communicator = Ice.initialize();


     | ^  22 |    }
  23 | 

However, when I put a breakpoint on this line in the browser debugger, I can see that Ice is defined and it has an initialize() function.

Here is a snippet of my code:

import './App.css';
import React from 'react';
import Ice from 'ice/lib/es5/Ice';

//const Ice = require("ice/lib/es5/Ice").Ice;
//import SecurityNS from "./ISenderSecurityIntf";
const SecurityNS = require("./ISenderSecurityIntf").SecurityNS

class App extends React.Component {
  constructor() {
    super();
    console.log(Ice);
    this.communicator = null;
    this.onConnect = this.onConnect.bind(this);
  }

  async onConnect() {

    if (this.communicator === null)
    {
      this.communicator = Ice.initialize();
    }
   ...
  }

  render()
  {
     // some stuff
   }

I do see this warning when I compile:

./src/ISenderSecurityIntf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

As you can see I have been toiling with how to properly import Ice into my program. Doing this line does not work for me:

const Ice = require("ice").Ice;

I get some error about m.require and several warnings like this:

Compiled with warnings.

./src/ISenderSecurityIntf.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/ice/src/IceStorm/IceStorm.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/ice/src/Ice/Metrics.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

./node_modules/ice/src/Ice/EndpointInfo.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted

Any ideas? Thank you.

Cassie

Comments

  • xdm
    xdm La Coruña, Spain

    Hi Cassie,

    I see you are using "create-react-app" the WebPack configuration included with create-react-app imports the Ice node module, but this doesn't work with browsers, to import the Ice.js from lib you need setup Ice as an external webpack module.

    create-react-app doesn't allow to customize the WebPack configuration, but you can use react-app-rewired to do that.

    npm install --save-dev react-app-rewired
    

    Create a config-overrides.js in the root of your project with the following contents:

    module.exports = function override(config, env) {
    
        config.externals = config.externals || {};
    
        config.externals = {
          ice: 'window'
        };
    
        return config;
    };
    

    In package.json replace the default start,build,test scripts with react-app-rewired

    "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      }
    

    should become:

    "scripts": {
        "start": "react-app-rewired start --scripts-version react-scripts",
        "build": "react-app-rewired build --scripts-version react-scripts",
        "test": "react-app-rewired test --env=jsdom --scripts-version react-scripts",
        "eject": "react-scripts eject"
      }
    

    In your index.html include Ice.js using a script tag, if you are using the es5 version you will also have to include the regenerator runtime

    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.12.1/polyfill.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ice/3.7.4/es5/Ice.js"></script>
    

    Then in your App.js

    import { Ice } from 'ice';
    import { Demo } from './Hello.js'
    

    For this to work you will have to use js:es6-module with your Slice definitions.

    Additionally, if you have several Slice definitions you can use the gulp-ice-builder to run slice2js and bundle all generated code in a module, see https://www.npmjs.com/package/gulp-ice-builder?activeTab=readme.

    You can also consider to setup react without using create-react-app, using gulp and babel.

    Let us know if you need more help with this setup.