html-webpack-plugin icon indicating copy to clipboard operation
html-webpack-plugin copied to clipboard

compilation.getAssetPath is not a function when using yarn workspaces

Open rubeniskov opened this issue 3 years ago • 14 comments

Expected behaviour

The way webpack version is resolved to determine which api to use in L162 and L540 delegates to nodejs the wepack resolution, this causes version mismatch in cases where the dependencies are hoisted. It should resolve the webpack.config.js where was required to determine the api version.

https://github.com/jantimon/html-webpack-plugin/blob/19b5122746c0a34c4a341ad1758eb743c87a4c55/index.js#L30

Current behaviour

This error is produced because @storybook/react uses a [email protected] version, and html-webpack-plugin is picking the root [email protected] instead of the local one.

(node:50947) UnhandledPromiseRejectionWarning: TypeError: compilation.getAssetPath is not a function
    at compiler.hooks.emit.tapAsync (.../cnix-ui/node_modules/html-webpack-plugin/index.js:164:25)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (.../cnix-ui/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
    at AsyncSeriesHook.lazyCompileHook (.../cnix-ui/node_modules/tapable/lib/Hook.js:154:20)
    at Compiler.emitAssets (.../cnix-ui/node_modules/@storybook/core/node_modules/webpack/lib/Compiler.js:491:19)
    at onCompiled (.../cnix-ui/node_modules/@storybook/core/node_modules/webpack/lib/Watching.js:51:19)
    at hooks.afterCompile.callAsync.err (.../cnix-ui/node_modules/@storybook/core/node_modules/webpack/lib/Compiler.js:681:15)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (.../cnix-ui/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:15:1)
    at AsyncSeriesHook.lazyCompileHook (.../cnix-ui/node_modules/tapable/lib/Hook.js:154:20)
    at compilation.seal.err (.../cnix-ui/node_modules/@storybook/core/node_modules/webpack/lib/Compiler.js:678:31)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (.../cnix-ui/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
    at AsyncSeriesHook.lazyCompileHook (.../cnix-ui/node_modules/tapable/lib/Hook.js:154:20)
    at hooks.optimizeAssets.callAsync.err (.../cnix-ui/node_modules/@storybook/core/node_modules/webpack/lib/Compilation.js:1423:35)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (.../cnix-ui/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
    at AsyncSeriesHook.lazyCompileHook (.../cnix-ui/node_modules/tapable/lib/Hook.js:154:20)
    at hooks.optimizeChunkAssets.callAsync.err (.../cnix-ui/node_modules/@storybook/core/node_modules/webpack/lib/Compilation.js:1414:32)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (.../cnix-ui/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:9:1)
(node:50947) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 8)

Environment

darwin 19.6.0
npm 6.13.4

yarn list webpack 
warning Filtering by arguments is deprecated. Please use the pattern option instead.
├─ @storybook/[email protected]
│  └─ [email protected]
├─ @storybook/[email protected]
│  └─ [email protected]
└─ [email protected]
✨  Done in 1.45s.

yarn list html-webpack-plugin
warning Filtering by arguments is deprecated. Please use the pattern option instead.
└─ [email protected]
✨  Done in 1.10s.

Posible Solution

It would be more simple if instead of use the version matching use a fallback call providing the newest api definition firts, ie:

--- html-wepack-plugin.cur	2020-11-01 12:19:09.450509028 +0100
+++ node_modules/html-webpack-plugin/index.js	2020-11-01 12:19:16.304563095 +0100
@@ -161,9 +161,8 @@
           hash: templateResult.mainCompilationHash
         };
 
-        const childCompilationOutputName = webpackMajorVersion === 4
-          ? compilation.mainTemplate.getAssetPath(this.options.filename, compiledEntries)
-          : compilation.getAssetPath(this.options.filename, compiledEntries);
+        const getAssetPath = (compilation.getAssetPath || compilation.mainTemplate.getAssetPath).bind(compilation);
+        const childCompilationOutputName = getAssetPath(this.options.filename, compiledEntries);
 
         // If the child compilation was not executed during a previous main compile run
         // it is a cached result

or even better if there is a global call polyfill like this:

const getAssetPath = (compilation, ...args) => compilation.getAssetPath ? compilation.getAssetPath(...args) : compilation.mainTemplate.getAssetPath(...args);

Another solution to keep the logic untouched would be resolve webpack version taking in mind which component is requiring this module, ie @storybook/react is requiring in its webpack config so resolving the webpack from the parent module will obtain the version used in webpack.config.js, but this is potentially dangerous and deprecated. so in favor of simplify the logic the polyfill solution would be the best choice.

Relevant Links

PR https://github.com/jantimon/html-webpack-plugin/pull/1547

rubeniskov avatar Nov 01 '20 11:11 rubeniskov

I will open a PR with the changes, I hope the changes will welcome to merge, :) have a nice day!

rubeniskov avatar Nov 01 '20 11:11 rubeniskov

Unfortunately this doesn't fully solve the problem as different webpack 5 versions collide too

jantimon avatar Nov 01 '20 11:11 jantimon

I just merged a fix into 5.0.0-alpha.9

jantimon avatar Nov 01 '20 12:11 jantimon

Thank you for so fast reply

I'm approaching to get a stable system to get webpack version and its plugins using simple logic when hoisting dependencies...

Webpack 4 Screenshot 2020-11-01 at 23 10 40

Webpack 5

Screenshot 2020-11-01 at 23 14 38

rubeniskov avatar Nov 01 '20 22:11 rubeniskov

use yarn add html-webpack-plugin@next -D, this resolve

deyvisonborges avatar Dec 09 '20 04:12 deyvisonborges

Thanks @deeborges @jantimon , this fixed it.

Was because of webpack@5 usage, as far as I can tell. Would be great to get in @latest if possible :)

Robbie-Cook avatar Jan 20 '21 02:01 Robbie-Cook

@Robbie-Cook yes I am trying to release it as @latest soon.

jantimon avatar Jan 20 '21 08:01 jantimon

@deeborges @jantimon, I used yarn add html-webpack-plugin@next -D and now I have "html-webpack-plugin": "^5.0.0-beta.6", in my package.json but still with running yarn storybook I face to reported error.

amerllica avatar Jan 23 '21 17:01 amerllica

@deeborges @jantimon , usei yarn add html-webpack-plugin@next -De agora estou "html-webpack-plugin": "^5.0.0-beta.6",no meu package.jsonmas ainda com rodando yarn storybookenfrento erro relatado.

check this project that I structured with webpack and storybook https://github.com/deeborges/archetype-react

deyvisonborges avatar Jan 23 '21 18:01 deyvisonborges

verify my package.json

deyvisonborges avatar Jan 23 '21 18:01 deyvisonborges

verify my package.json

I tesed it, but I faced with same error

nimahkh avatar Jan 24 '21 14:01 nimahkh

strange. here it's working normally ...

note that I'm using the following version "html-webpack-plugin": "5.0.0-alpha.15",

Alt text

deyvisonborges avatar Jan 24 '21 21:01 deyvisonborges

is there a solution here that doesn't require installing an unnecessary dependency? with server-side rendering, i'm not using html-webpack-plugin

worc avatar Feb 03 '21 22:02 worc

Thanks for the help above. I ran into this in my Storybook build job as well today.

npx build-storybook --output-dir storybook-static/src

Errors:

TypeError: compilation.getAssetPath is not a function

Resolved it by manually adding this dependency:

npm install html-webpack-plugin --save-dev

Feels like a bandaid, but it works for now.

dep avatar Mar 16 '22 13:03 dep

Solved, now we use const webpack = compiler.webpack;, so there are no problems with the latest verison anymore, please update to the latest stable version and feel free to feedback

alexander-akait avatar Jun 10 '23 18:06 alexander-akait