Html-webpack-plugin: RangeError: Maximum call stack size exceeded

Created on 29 Mar 2019  路  21Comments  路  Source: jantimon/html-webpack-plugin

Expected behaviour

html-webpack-plugin should build without any error

Current behaviour

when building more then 245 html-webpack-plugins you will get a RangeError

Environment

operating system: Windows 10
Node.js version: 11.13.0
npm version: 6.7.0
webpack 4.29.6
html-webpack-plugin 4.0.0-beta.5

Relevant Links

I have created an example branch with the current issue

https://github.com/CT1994/html-webpack-plugin-range-error

example as zip

Most helpful comment

thank you i have raised a issue on webpack git to raise the issue also, i had no idea who to contact to get information about what is happening within webpack and the plugin

All 21 comments

OH 馃槰

This looks horrible
I got the same thing on mac with 355 plugin instances.

Node.js v10.13.0
darwin 17.7.0
6.4.1

Click to expand Stacktrace

Unhandled rejection RangeError: Maximum call stack size exceeded
    at new Function (<anonymous>)
    at AsyncSeriesHookCodeFactory.create (node_modules/tapable/lib/HookCodeFactory.js:32:10)
    at AsyncSeriesHook.compile (node_modules/tapable/lib/AsyncSeriesHook.js:24:18)
    at AsyncSeriesHook._createCall (node_modules/tapable/lib/Hook.js:24:15)
    at AsyncSeriesHook.lazyCompileHook [as callAsync] (node_modules/tapable/lib/Hook.js:153:21)
    at Compiler.emitAssets (node_modules/webpack/lib/Compiler.js:441:19)
    at onCompiled (node_modules/webpack/lib/Compiler.js:241:9)
    at hooks.afterCompile.callAsync.err (node_modules/webpack/lib/Compiler.js:630:14)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
    at compilation.seal.err (node_modules/webpack/lib/Compiler.js:627:30)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
    at hooks.optimizeAssets.callAsync.err (node_modules/webpack/lib/Compilation.js:1325:35)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook (node_modules/tapable/lib/Hook.js:154:20)
    at hooks.optimizeChunkAssets.callAsync.err (node_modules/webpack/lib/Compilation.js:1316:32)
    at _err0 (eval at create (node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:11:1)
    at taskRunner.run (node_modules/terser-webpack-plugin/dist/index.js:319:9)
    at step (node_modules/terser-webpack-plugin/dist/TaskRunner.js:83:9)
    at _cacache.default.get.then (node_modules/terser-webpack-plugin/dist/TaskRunner.js:107:15)
    at tryCatcher (node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:512:31)
    at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (node_modules/bluebird/js/release/promise.js:694:18)
    at Promise._fulfill (node_modules/bluebird/js/release/promise.js:638:18)
    at Promise._resolveCallback (node_modules/bluebird/js/release/promise.js:432:57)
    at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:524:17)
    at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:569:18)
    at Promise._settlePromise0 (node_modules/bluebird/js/release/promise.js:614:10)
    at Promise._settlePromises (node_modules/bluebird/js/release/promise.js:694:18)
    at Promise._fulfill (node_modules/bluebird/js/release/promise.js:638:18)
    at Promise._resolveCallback (node_modules/bluebird/js/release/promise.js:432:57)
    at Promise._settlePromiseFromHandler (node_modules/bluebird/js/release/promise.js:524:17)
    at Promise._settlePromise (node_modules/bluebird/js/release/promise.js:569:18)

Maybe it is a problem with bluebird which is added by cachable:

html-webpack-plugin-range-error > webpack > terser-webpack-plugin > cacache > bluebird

But honestly I have no clue why this is happening.

one solution that i have found is using tap on the emit hook
https://github.com/jantimon/html-webpack-plugin/blob/25465510df1633f76005f430b098cc7783e0495b/index.js#L171

for some reason this work and async does not which lets me believe that there is a issue with tapable
https://github.com/webpack/tapable

fyi using tap will also break but there is a higher threshold of plugins

I guess that鈥檚 a limitation of the webpack plugin system.

Unfortunately the html-webpack-plugin was not build to generate multiple html files and allowing it would require a major rewrite 馃様

@jantimon here is a example of what you can possibly do without making a breaking change for anyone
https://github.com/CT1994/html-webpack-plugin

there is a error in postProcessHtml which i dont fully understand but you are able to run as many html-webpack-plugins

I was able to write out 5000 html files of stack error trace within the files

The main change is there is a masterCompiler.js which gets all instances of html webpack plugin from webpack and process all plugins within the masterCompiler

edit update: I was able to fix the compile issue and have a very basic example of html-webpack-plugin multiple html generator without users having to change there plugin options.

Wow cool!

Could you explain what's the difference to the current implementation?
It's quite hard to get that from the code because it is so much..

Right now it is also using only 1 compiler for all instances

ok here is what is happening.

https://github.com/CT1994/html-webpack-plugin/blob/6880e69f8f167fd953766d92cf8d15b1217c4e36/index.js#L73-L88

  1. in apply i am grabbing all the html-webpack-plugins from webpack plugins config and passing it to the masterCompiler

  2. i then add the masterCompiler to webpack plugin before all other plugins to make sure html-webpack-plugins still work correctly.

  3. the masterCompiler then take control and process all the individual html-webpack-plugin and only every calls back once for each of webpack hooks to keep the callstack down so you don't hit maximum call stack limit.

just tested this at work development mode work, production is still broken not 100% what is causing the issue in production

Hm maybe we can ask the webpack team how that might happen.
It sounds like there is a serious bug inside the html-webpack-plugin

thank you i have raised a issue on webpack git to raise the issue also, i had no idea who to contact to get information about what is happening within webpack and the plugin

Good news, the html-webpack-plugin has been fixed with the forked branch,
I found the issue which broke my company build, looks like a issue with another plugin.

if you would like me to make a pull request i would need time to clean up the changes I made and document it better for future reference.

Unfortunately this solution introduces memory leaks and works around the tappable plugin.
Not sure if we can merge that for so many users.
Perhaps @sokra could take a look why tappable is having these problems

@jantimon
understandable would be nice to know if there is any issue with tapable hopefully we hear form sokra

This is solved in a sub-optimal way in tapable. Need to be fixed there.

Thanks a lot @sokra for replying during your parental leave 馃憤

thank you @sokra 馃憤
@jantimon I've closed the pull request, happy for you to close this issue

Thanks @CT1994 for all your work - I would like to keep this issue open until a fix of tapable can resolve this problem

@jantimon
looking into tapable, very confused and will take me a while to get up to speed.
I believe the issue is within this recursive function https://github.com/webpack/tapable/blob/2a07fea1dc1f05a2d1de3c9e4be385947596a87d/lib/HookCodeFactory.js#L210-L239

@CT1994 :+1: yep you are right.

I tried your repro repo with 10,000 Plugins and it works... (took 170s to compile...)

@sokra thank you for all the help

Was this page helpful?
0 / 5 - 0 ratings