Skip to content

"RangeError: Maximum call stack size exceeded" when compiling a file with many requires #771

Closed
@Gobie

Description

@Gobie

Created based on comment #689 (comment)

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
Given CSS file with 10000 or more classes with URLs, in our case generated from sprites.

...
.classN { ... background-image: url(./path/to/sprite.png); ... }
...

The css-loader creates such a JS file, which on compile throws RangeError: Maximum call stack size exceeded.

...
exports.push([
  module.id, 
  ".class0 { background-image: url(" +
  escape(require("./path/to/sprite.png")) +
  "); }.class1 { background-image: url(" +
  escape(require("./path/to/sprite.png")) +
  ...
])

What is the expected behavior?
The expected behaviour is to generate a JS file, which can be compiled and executed.

Please mention other relevant information such as your webpack version, Node.js version and Operating System.
Reproducible on 1.0.0, Node 6.11.3 & Node 8.9.4.

Technical details
The issue is that URLs are replaced by requires and cssAsString in loader.js is built by string concatenation "..." + "..." + ... + "..." which has upper limit in each version of v8, given by it's default stack size.

Experimentally measured:

  • node 6.11.3 has ~6250 strings,
  • node 8.9.4 has ~3285 strings.

The fix is straightforward, group the string concatenations by fixed amount so it can be compiled using default stack size. ("..." + ... + "...") + ("..." + ... + "...")

Smallest possible test-case for css-loader

/*globals describe */

var helpers = require("./helpers");
var test = helpers.test;

describe("string concat", function() {
	this.timeout(20000);

	var actualCSS, expectedCSS, i;

	actualCSS = '';
	expectedCSS = '';
	for (i = 0; i < 10000; i++) {
		actualCSS += ".class" + i + " { background-image: url(./path/to/file.png); }";
		expectedCSS += ".class" + i + " { background-image: url({./path/to/file.png}); }";
	}

	test("should handle concat of 20001 strings", actualCSS, [[1, expectedCSS, ""]]);
});

Repo with reproducible test-case https://github.com/Gobie/css-loader/tree/issue-771

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions