Search code examples
reactjswebpackcodemirroruglifyjs

Issue with Webpack 4.1.1 and UglifyJS2 - Production mode mangles code which throws uncaught error


I've upgraded a project to Webpack 4.1.1 and encountered a bug with UglifyJS that I cant seem to get around.

Minimum reproducible repo here: https://github.com/jamesopti/uglifyjs-webpack-issue

Although I think this is a bug, I'd like to try and configure UglifyJS to work around it. No luck so far despite the options shown below.

uglifyOptions: {
  mangle: false,
  keep_classnames: true,
  keep_fnames: true,
},

Any ideas?

Main.js code:

import React from 'react';

import { render } from 'react-dom';
import ReactCodeMirror from 'react-codemirror';

// Enables syntax highlighting for javascript
require('codemirror/mode/javascript/javascript');
// Enables linting for javascript
require('codemirror/addon/lint/lint');
require('codemirror/addon/lint/javascript-lint');

window.JSHINT = require('jshint').JSHINT;

const defaultOptions = {
  lint: true,
};

render(
  <ReactCodeMirror
    options={defaultOptions}
    value={'some\ncode'}
  />, document.querySelector('#root')
);

Webpack config:

  entry: './src/main.js',

  mode: 'development',

  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },

  module: {
    rules: [
      { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader' } ] },
      { test: [/\/src\/(?:.*)\.js$/], use: { loader: 'babel-loader' } },
    ]
  },

  optimization: {
    minimizer: [
      new UglifyJsPlugin({
        cache: true,
        parallel: true,
        uglifyOptions: {
          mangle: false,
          keep_classnames: true,
          keep_fnames: true,
        },
      }),
    ]
  }

Error rendering component


Solution

  • The root cause of this is a bug in UglifyJS (reported here).

    Minimal reproducible code:

    (function(mod) {
      mod();
    })(function() {
      function getMaxSeverity(ax, bx) {
        if (ax === "error") {
          return ax;
        } else {
          return bx;
        }
      }
      function main() {
        var arr = ['hey'];
        for (var i = 0; i < arr.length; i++) {
          console.log(getMaxSeverity('one', 'two'));
        }
      }
      main();
    });
    

    The workaround is the compress inline option

    optimization: {
      minimizer: [
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              inline: 1,
            }
          }
        })
      ]
    }