jodit: Image upload does not work after building for production version

I am trying to upload image in a react application. I have used the jodit-react library for this. This worked fine in development mode. But after pushing to production, it didn’t. It was throwing an error in the bottom right side of the editor saying Need URL for AJAX request. Considering that might be a problem of jodit-react library, I tried to use the original one. But this was also throwing the same error.

Jodit Version: 3.2.44

Code

import React, {Component} from "react";
import buttons from './customButtons';
import 'jodit/build/jodit.min.js';

class CustomEditor extends Component {
  editor;
  editorRef = React.createRef();

  config = {
    uploader: {
      buttons,
      url: 'https://xdsoft.net/jodit/connector/index.php?action=fileUpload'
    }
  };

  componentDidMount() {
    this.createEditor();
  }

  createEditor() {
    this.editor && this.editor.destruct();
    this.editor = new Jodit(this.editorRef.current, this.config);

    this.editor.value = this.props.content;
    this.editor.events.on('change', this.props.onChange);
  }

  componentWillUnmount() {
    this.editor && this.editor.destruct();
  }

  render() {
    return (
      <textarea ref={this.editorRef}/>
    );
  }
}

export default CustomEditor;

Expected behavior: Image upload should work in both production and development mode in react.

Actual behavior: screenshot 2019-03-04 at 9 16 13 pm

Note: I could have created the issue under jodit-react repo, but that one doesn’t look very active like this one. But in case you want to move it there, kindly let me know.

About this issue

  • Original URL
  • State: open
  • Created 5 years ago
  • Reactions: 8
  • Comments: 17

Most upvoted comments

The issue is in isJoditObject:

export const isJoditObject = (jodit: unknown): jodit is IJodit  => {
    if (jodit && jodit instanceof Object && typeof jodit.constructor === 'function' && jodit.constructor.name === 'Jodit') {
        return true;
    }

    return false;
};

jodit.constructor === 'function' && jodit.constructor.name === 'Jodit' does not work since the constructor name gets mangled, so this returns false for jodit.constructor.name === 'Jodit' You are better off setting boolean within the Jodit class isJodit = true.

Workaround for this issue for Laravel Mix, use config below in webpack.mix.js:

   mix.options({
       uglify: {
           uglifyOptions: {
               mangle: {
                   reserved: ['Jodit'],
               },
           },
       },
   })

I found the solution which works on both development and production build…

solved using UglifyJsPlugin, config changes in webpack…

optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true, extractComments: false, uglifyOptions: { ie8: false, mangle: { reserved: ['Jodit'], }, compress: { if_return: true, unused: true, booleans: true, properties: true, dead_code: true, pure_getters: true, unsafe: true, unsafe_comps: true, drop_console: true, passes: 2 }, output: { comments: false, beautify: false, }, minimize: true } }), ], },

I found this config setting in jodit editor demo project… https://xdsoft.net/jodit/

download project and check in the webpack config file.

For laravel mix, if its version is 4 or higher use the following config in webpack.mix.js

mix.options({
   terser: {
      terserOptions: {
         mangle: {
            reserved: ['Jodit'],
         },
      }
   }
})

If you use WebPack4, the solution is install terser-webpack-plugin

npm install terser-webpack-plugin --save-dev

and in module.export put:

optimization: { minimizer: [ new TerserPlugin({ terserOptions: { ecma: undefined, warnings: false, parse: {}, compress: {}, mangle: true, // Note mangle.propertiesisfalse by default. module: false, output: null, toplevel: false, nameCache: null, ie8: false, keep_classnames: undefined, keep_fnames: true, safari10: false } }) ] }

You can configure the minimizer to ignore the Jodit function name during mangle. I achieve this in Vue by editing vue.config.js as follows;

module.exports = {
  configureWebpack: config => {
    const terserOptions = config.optimization.minimizer[0].options.terserOptions;

    // Set regex to ignore Jodit function name
    terserOptions.keep_fnames = /^Jodit/;
  }
}

How you would do this in React I am not sure. But I am sure it would be similar.

Same thing in production mode! It’s like he did not take part of the given configuration.

By inspecting in the console the editor object created you can see how it does not have all the configurations given to the uploader options.