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

Maximum call stack size exceeded in webpack build with 3.14.0 version #5098

Closed
dimitriylol opened this issue Jul 23, 2021 · 11 comments · Fixed by #5099
Closed

Maximum call stack size exceeded in webpack build with 3.14.0 version #5098

dimitriylol opened this issue Jul 23, 2021 · 11 comments · Fixed by #5099
Labels

Comments

@dimitriylol
Copy link

Uglify version (uglifyjs -V): 3.14.0

JavaScript input: n/a

The uglifyjs CLI command executed or minify() options used. n/a

JavaScript output or error produced.

The error stack trace from browser:

setPrototypeOf.js:1 Uncaught RangeError: Maximum call stack size exceeded
    at t (setPrototypeOf.js:1)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)
    at t (setPrototypeOf.js:8)

setPrototypeOf is @babel/runtime/helpers/setPrototypeOf.js.

Related to build packages and their version:

    "uglifyjs-webpack-plugin": "^2.2.0",
    "@babel/cli": "^7.8.3",
    "@babel/core": "^7.8.3",
    "@babel/plugin-proposal-class-properties": "^7.8.3",
    "regenerator-runtime": "^0.13.7",
    "core-js": "^3.15.2",
    "@babel/eslint-parser": "^7.8.3",
    "@babel/preset-env": "^7.8.3",
    "@babel/preset-react": "^7.8.3",
    "@babel/preset-typescript": "^7.8.3",
    "webpack": "4.44.2",

Webpack plugin usage:

      new UglifyJsPlugin({
        sourceMap: false,
        parallel: true
      }),

As a workaround I added "uglify-js": "3.13.10" to my package.json to overrule dependencies from uglifyjs-webpack-plugin:

"dependencies": {
    "uglify-js": "^3.6.0"

If I miss adding the required information about steps to reproduce the issue, please let me know.

@bruce007lee
Copy link

bruce007lee commented Jul 23, 2021

same issue, plz fix it ASAP

@alexlamsl
Copy link
Collaborator

If I miss adding the required information about steps to reproduce the issue, please let me know.

@dimitriylol the part of report that you've replaced with n/a contains the instructions to provide the required information when you file this report:

A complete parsable JS program exhibiting the issue with UglifyJS alone - without third party tools or libraries.

Ideally the input should be as small as possible, but may be large if isolating
the problem proves to be difficult. The most important thing is that the
standalone program reliably exhibits the bug when minified. Provide a link to a
gist if necessary.

Solely providing minified output without the original uglify JS input is not
useful in determining the cause of the problem. Issues without a reproducible
test case will be closed.

It even provided steps to produce a proper test case without third party libraries:

For users using bundlers or transpilers, you may be able to gather the required
information through setting the UGLIFY_BUG_REPORT environment variable:

    export UGLIFY_BUG_REPORT=1      (bash)
    set UGLIFY_BUG_REPORT=1         (Command Prompt)
    $Env:UGLIFY_BUG_REPORT=1        (PowerShell)

before running your usual build process. The resulting "minified" output should
contain the necessary details for this report.

Please fill them out as required, otherwise I have no way to move forward on this.

@dimitriylol
Copy link
Author

@alexlamsl fair enough. I can't give the whole code but I'll try to create a minimal repo to reproduce the issue. I'll do it later today (in 6-7 hours).

@dimitriylol
Copy link
Author

I couldn't create the minimal repo to reproduce because I can't print uglify options. Here is what I got:

JavaScript input:
The error is thrown on recursive call of setPrototypeOf function from @babel/runtime/helpers/inheritsLoose.js:

var setPrototypeOf = require("./setPrototypeOf.js");

function _inheritsLoose(subClass, superClass) {
  subClass.prototype = Object.create(superClass.prototype);
  subClass.prototype.constructor = subClass;
  setPrototypeOf(subClass, superClass);
}

module.exports = _inheritsLoose;
module.exports["default"] = module.exports, module.exports.__esModule = true;

The _inheritsLoose function call that leads to error is done from jss/dist/jss.esm.js, line 236. I published gist of it.

The uglifyjs CLI command executed or minify() options used:

I failed to find the exact uglifyjs option that leads to the error. When I use the suggestion of exporting UGLIFY_BUG_REPORT=1 I don't get the error at all. The minified code executed without errors. I printed options that are used by uglifyjs-webpack-plugin. Here they are:

{ warnings: undefined,
  parse:
   { toplevel:
      { globals: [Object],
        uses_eval: false,
        uses_with: false,
        body: [Array],
        enclosed: [Array],
        functions: [Object],
        make_def: [Function],
        parent_scope: null,
        variables: [Object],
        start: [Object],
        end: [Object],
        _squeezed: true,
        _optimized: true,
        _var_names: [Object],
        to_mangle: [] },
     filename: 'static/js/main.9e685cd4.js' },
  compress: {},
  mangle: true,
  output:
   { shebang: true,
     comments: /^\**!|@preserve|@license|@cc_on/i,
     beautify: false,
     semicolons: true },
  sourceMap: true,
  toplevel: undefined,
  nameCache: undefined,
  ie8: undefined,
  keep_fnames: undefined }

I can't print parse fully because it has recursive links in it. When I copied options except that parse part and launched uglify-js as the following:

import uglifyJs from 'uglify-js'
import fs from 'fs'

const uglifyOptions = {
    warnings: undefined,
    compress: {},
    mangle: true,
    output:
    {
        shebang: true,
        comments: /^\**!|@preserve|@license|@cc_on/i,
        beautify: false,
        semicolons: true
    },
    sourceMap: true,
    toplevel: undefined,
    nameCache: undefined,
    ie8: undefined,
    keep_fnames: undefined
}

const { code } = uglifyJs.minify({
    'jss.esm.js': fs.readFileSync('./node_modules/jss/dist/jss.esm.js').toString()
}, uglifyOptions);

fs.writeFileSync('after_uglify.js', code)

I can launch after_uglify.js without the Maximum call stack size exceeded error. Therefore those options aren't very helpful.

@alexlamsl please clarify maybe there is another way to get those options? Maybe is there a simple way to compare minified files with/without UGLIFY_BUG_REPORT variable to understand what changes the behavior?

@mycoin
Copy link

mycoin commented Jul 23, 2021

same issue, another sample case:

./package.json

{
  "dependencies": {
    "@babel/core": "^7.14.8",
    "@babel/preset-env": "^7.14.8",
    "uglifyjs-webpack-plugin": "^2.2.0",
    "webpack": "^5.46.0",
    "webpack-cli": "^4.7.2"
  },
  "scripts": {
    "build": "webpack"
  }
}

index.js

require('@babel/runtime/helpers/extends')({},{})

webpack.config.js

const UglifyWebpackPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
    mode: 'production',
    entry: './index.js',
    optimization: {
        minimizer: [
            new UglifyWebpackPlugin(),
        ],
    }
}

.babelrc

{
  "presets": ["@babel/preset-env"]
}

then ...
image

@alexlamsl
Copy link
Collaborator

Did you follow the instructions for UGLIFY_BUG_REPORT? You can simply run your existing workflow and get all the necessary information for the report at the end.

Here's an example from a prior report:
#4612 (comment)

Meanwhile, if @bruce007lee and others can provide actionable information as well that would also help in resolving this "ASAP".

@alexlamsl
Copy link
Collaborator

@mycoin please follow #5098 (comment) and provide a runnable test case.

@mycoin
Copy link

mycoin commented Jul 23, 2021

@mycoin please follow #5098 (comment) and provide a runnable test case.

code from @babel/runtime/helpers/extends

const cModules = {}

function _extends() {
  cModules.exports = _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];
      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }
    return target;
  };
  return _extends.apply(this, arguments);
};

console.log('>>', _extends({}, {ok: 1}));

@alexlamsl
Copy link
Collaborator

@mycoin for future reference, if you follow the instructions with:

$ export UGLIFY_BUG_REPORT=1
$ npm run build

You would get the follwoing dist/main.js

// UGLIFY_BUG_REPORT
// {
//   "parse": {},
//   "compress": {},
//   "mangle": true,
//   "output": {
//     "shebang": true,
//     "comments": {},
//     "beautify": false,
//     "semicolons": true
//   },
//   "sourceMap": null
// }

//-------------------------------------------------------------
// main.js
/******/ (() => { // webpackBootstrap
/******/ 	var __webpack_modules__ = ({

/***/ 154:
/***/ ((module) => {

function _extends() {
  module.exports = _extends = Object.assign || function (target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = arguments[i];

      for (var key in source) {
        if (Object.prototype.hasOwnProperty.call(source, key)) {
          target[key] = source[key];
        }
      }
    }

    return target;
  };

  module.exports.default = module.exports, module.exports.__esModule = true;
  return _extends.apply(this, arguments);
}

module.exports = _extends;
module.exports.default = module.exports, module.exports.__esModule = true;

/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
var __webpack_exports__ = {};
// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
(() => {
__webpack_require__(154)({},{})

})();

/******/ })()
;

which contains all the necessary information to reproduce the bug with uglify-js alone.

@alexlamsl alexlamsl added the bug label Jul 23, 2021
alexlamsl added a commit to alexlamsl/UglifyJS that referenced this issue Jul 23, 2021
alexlamsl added a commit that referenced this issue Jul 23, 2021
@dimitriylol
Copy link
Author

@alexlamsl thanks for the fix!

@alexlamsl
Copy link
Collaborator

Patch released in uglify-js@3.14.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants