partridgejiang / Kekule.js

A Javascript cheminformatics toolkit.
http://partridgejiang.github.io/Kekule.js
MIT License
250 stars 61 forks source link

[RESOLVED] Cannot use with React in production (TypeError: e is not a function) #124

Closed antonintlh closed 5 years ago

antonintlh commented 5 years ago

Hello!

I'm currently trying to use Kekule.js within a React web application (React v16.8.4 not ejected). It works very well in development environment (with built-in React/webpack development server), but when I build my project and deploy it behind a web server, the application won't load at all.

No matter the code I write, the application crashes at import Kekule from 'kekule';.

Here is the only "stack trace" I have in production environment. dev-console When I want to view the minified source code, it sends me to this (line 29968): minified-code I think it is this function: https://github.com/partridgejiang/Kekule.js/blob/master/src/widgets/kekule.widget.base.js#L4508.

Thank you in advance for your help!

Antonin

partridgejiang commented 5 years ago

It seems the problem is caused during the js minimization process. The "magic" parameter $super in function initialize is converted to e with a value lost. Therefore, you may have to explicitly preserve the $super (and some other magic paramters) in the js compression tool. For example, for uglifyES using following the config:

'uglifyES': {
  mangle: { reserved: ['$super', '$origin'] }
},
antonintlh commented 5 years ago

Hello,

Thank you for your answer.

Since my first message, I found how to resolve that with CRACO (which permit me to update Webpack config without ejecting), but I was disabling all minify options for Kekule.

module.exports = {
  mode: 'extends',
  webpack: {
    configure: (webpackConfig) => {
      const config = webpackConfig;
      config.optimization.splitChunks.cacheGroups = {
        kekule: {
          name: 'kekule',
          priority: 10,
          reuseExistingChunk: false,
          test: /kekule/,
        },
      };
      config.optimization.minimizer[0].options.chunkFilter = chunk => chunk.name !== 'kekule';
      return config;
    },
  },
};

I updated my Webpack config to match with your answer and keep minify without mangling $super and $origin, and it works!

module.exports = {
  mode: 'extends',
  webpack: {
    configure: (webpackConfig) => {
      const config = webpackConfig;
      config.optimization.splitChunks.cacheGroups = {
        kekule: {
          name: 'kekule',
          priority: 10,
          reuseExistingChunk: false,
          test: /kekule/,
        },
      };
      config.optimization.minimizer[0].options.terserOptions.mangle.reserved = ['$super', '$origin'];
      return config;
    },
  },
};

Thank you for your help!