mini-css-extract-plugin: Misleading error, when used with `html-webpack-plugin`

  • Operating System: macOS 10.15.2
  • Node Version: v10.17.0
  • NPM Version: 6.11.3
  • webpack Version: webpack@4.41.5 webpack-cli@3.3.10
  • mini-css-extract-plugin Version: mini-css-extract-plugin@0.9.0

Expected Behavior

Error thrown that lead to something meaningful (still not sure what actually goes wrong)

Actual Behavior

Thrown the error in some third-party lib

% npm run build -- --mode development

> example@1.0.0 build /Users/user/foo
> webpack "--mode" "development"

/Users/user/foo/node_modules/neo-async/async.js:16
    throw new Error('Callback was already called.');
    ^

Error: Callback was already called.
    at throwError (/Users/user/foo/node_modules/neo-async/async.js:16:11)
    at /Users/user/foo/node_modules/neo-async/async.js:2818:7
    at process._tickCallback (internal/process/next_tick.js:61:11)

Code

https://gist.github.com/ogonkov/2e23941414d6f0b3d5328bd80cba5674

How Do We Reproduce?

  1. Checkout gist above
  2. npm i
  3. npm run build

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 11
  • Comments: 38 (13 by maintainers)

Commits related to this issue

Most upvoted comments

CSS-related issues in html-webpack-plugin:

it’s probably mini-css-extract-plugin issue

Issues in mini-css-extract-plugin:

it’s probably html-webpack-plugin issue

Hit that issue as well, cost me a few hours already 😦 Thanks @ogonkov for reporting with reproducer.

@klesun a viable workaround (works for me) might be to replace MiniCssExtractPlugin by a simple file-loader :

      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'file-loader',
            options: {
              esModule: false,
            },
          },
          'extract-loader',
          {
            loader: 'css-loader',
            options: {
              esModule: false,
            },
          }
        ],
      },

If you also have regular JS imports then of course 2 distinct CSS rules are required.

UPDATE: just found that stackoverflow entry… 😉 Hopefully still useful to have the workaround detailed here.

I believe that error thrown from webpack/lib/Compilation

https://github.com/webpack/webpack/blob/45ecebc9f0486c43efc7b56f2c31426d94a55264/lib/Compilation.js#L849

Callback is first called in catch on line 829, then in addModuleDependencies it called again around https://github.com/webpack/webpack/blob/45ecebc9f0486c43efc7b56f2c31426d94a55264/lib/Compilation.js#L1020

If i put console log on 1020 it shows that css file come here twice.

Second invocation is seems to come from loader child compiler callback invocation (redundant?)

When I use style-loader I get “ReferenceError: document is not defined”. When I use MiniCssExtractPlugin I get "Error: Callback was already called.

@evilebottnawi, I think this is still a problem of MCEP. Simply say, MCEP do not support child compilation.

HWP use child compilation to parse html and its dependencies, and MCEP didn’t add the CssDependency (& factory) to childCompilation.dependencyFactories. Of course, when a html has a css dependency, then the problem.

Maybe, change the hook of thisCompilation to compilation will solve this, mini-css-extract-plugin/src/index.js#L63.

If child compilation exists, should not MCEP support it?

If this helps, I created one more minimal test case: https://github.com/klesun-misc/mcep_issue_489 (this one without ejs, just plain html)

Unfortunately spoke too soon. Changing the hook indeed fixes the compilation and all files are properly emitted but the identifier inside the requiring file gets changed from the original .js file (which generates the css) into a .css file instead (the emitted file) 😔

I’ll try and reduce the build code and create a playground repo. Will probably take me some time

@IgnusG can you provide minimum reproducible test repo?

@jantimon

But we will probably need child compilations for ssr.

pitch phase do not break SSR

Isn’t !! only to exclude loaders?

Yes, it is exclude pre loader and normal loader, but because you will use pitch it will run loader anyway because you will pass them in a string require/import, you can look how mini-css-extract-plugin work

@ogonkov sorry for delay, a lot of work, can you send a PR?

I ended up just moving all my <link href="..."> references to the entry js file as import '...';s, since this plugin does not seem to work with html without Callback was already called error even on a plain minimal test case for me. Even though docs are implying that it is supposed to

@ogonkov i think something wrong in HWP, i will look at this in near future