webpack-contrib / mini-css-extract-plugin

Lightweight CSS extraction plugin
MIT License
4.67k stars 389 forks source link

"installedCssChunks is not defined" after 2.9.0 update #1110

Closed michaelfaith closed 1 month ago

michaelfaith commented 3 months ago

After upgrading from 2.8.1 to 2.9.0 (and then 2.9.1), we're seeing this error repeatedly in the Chrome dev console. We didn't change any aspect of our config or css loading set-up.

image

I believe this is related to this change: https://github.com/webpack-contrib/mini-css-extract-plugin/pull/1043

Plugin config

...
  {
        test: /\.less$/,
        include: [path.join(appDirectory, 'stylesheets')],
        exclude: [],
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader',
            options: {
              sourceMap: DEV,
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              postcssOptions: {
                plugins: [require('autoprefixer')],
              },
              sourceMap: DEV,
            },
          },

          {
            loader: 'less-loader',
            options: {
              lessOptions: {
                math: 'always',
              },
              sourceMap: DEV,
            },
          },
        ],
      },
...
plugins: [
   ...
  new MiniCssExtractPlugin({
      experimentalUseImportModule: true,
      filename: '[name].[contenthash:20].css',
    }),
  ...
]

Please paste the results of npx webpack-cli info here, and mention other relevant information

System:
    OS: macOS 14.6.1
    CPU: (12) arm64 Apple M3 Pro
    Memory: 1.10 GB / 36.00 GB
  Binaries:
    Node: 20.12.2 - ~/.nvm/versions/node/v20.12.2/bin/node
    npm: 10.8.2 - ~/.nvm/versions/node/v20.12.2/bin/npm
  Browsers:
    Chrome: 127.0.6533.120
    Safari: 17.6
  Packages:
    babel-loader: ^9.1.3 => 9.1.3 
    css-loader: ^6.11.0 => 6.11.0 
    expose-loader: ^5.0.0 => 5.0.0 
    json-loader: ~0.5.7 => 0.5.7 
    less-loader: ^12.2.0 => 12.2.0 
    postcss-loader: ^8.1.1 => 8.1.1 
    source-map-loader: ^5.0.0 => 5.0.0 
    style-loader: ^4.0.0 => 4.0.0 
    webpack: ^5.93.0 => 5.93.0 
    webpack-cli: ^5.1.4 => 5.1.4 
alexander-akait commented 3 months ago

Please create reproducible test repo, otherwise I can't help, thank you

lukpsaxo commented 3 months ago

We are also seeing the issue, in watch mode only and only on certain usage patterns of split bundles. We will try and help with more info by debugging within a few weeks unless someone beats us to it.

michaelfaith commented 3 months ago

We will try and help with more info by debugging within a few weeks unless someone beats us to it.

Thanks, that would be super helpful. We're in a large private monorepo, and it'll be a bit before I can try and create a public repro to share.

alexander-akait commented 3 months ago

Yeah, I am glad to help with it, but wihtour more information, it is hard, it happends only in 2.9.0?

michaelfaith commented 2 months ago

Yeah, I am glad to help with it, but wihtour more information, it is hard, it happends only in 2.9.0?

I appreciate it. Yes, we were on 2.8.1 for a while without issue. This only started happening after updating to 2.9, and I believe it's related to that change I linked specifically.

alexander-akait commented 2 months ago

I think it can be due it - https://github.com/webpack-contrib/mini-css-extract-plugin/commit/ee25e51a8d06292dd8643f5bf1d6c4faa51c4f4c, do you have Preload or Prefetch for you dynamic chunks?

alexander-akait commented 2 months ago

Looks like withPrefetch && hasCssMatcher or withPreload && hasCssMatcher is true, but it should happens, can you try to debug it locally?

michaelfaith commented 2 months ago

For sure, I can debug it locally. I'll have to set that branch back up, but that won't take a long.

michaelfaith commented 2 months ago

We aren't doing any prefetching ourselves, but from what I can tell, this seems to always be breaking on a chunk that's coming from a library we're using that's calling import with webpackPrefetch: true. That chunkId seems to always be the one that's going through this mini-css code where installedCssChunks is undefined:

image

The library in question is just passing the import function into React.lazy. We're not preloading / prefetching our css chunks at all.

alexander-akait commented 2 months ago

@michaelfaith Maybe you can try to create reproducible test repo with this library, look like you have CSS chunks before, but then it was removed for bundle, but runtime code already was created

Plonq commented 1 month ago

I am running into this issue as well, in an Angular 18 app. mini-css version is 2.9.0. If I change all three instances of the /* webpackPrefetch: true */ magic comment to /* webpackPrefetch: false */ (EDIT: false is not actually a valid value, but it has the same effect as removing the comment entirely) then the error goes away. EDIT because it seems to be one error per instance of this magic comment.

I'll try to provide a minimal repro if I can. EDIT: no luck with a fresh webpack-based Angular 18 app.

alexander-akait commented 1 month ago

@Plonq Where do you change /* webpackPrefetch: false */? Can you show me a code?

alexander-akait commented 1 month ago

If someone gives me the code that causes this problem, then I will be able to fix it, logically this cannot happen at all

Plonq commented 1 month ago

@Plonq Where do you change /* webpackPrefetch: false */? Can you show me a code?

If you have no instances of /* webpackPrefetch: true */ then you must not have the same issue as me. But, as per the docs, it's a magic comment used in a dynamic import, like so:

import(
  /* webpackPrefetch: true */
  "some-file.js"
);

EDIT: I misunderstood, I thought you were someone with the same error. Here's some real code from one place we use that:

    import(
      /* webpackChunkName: "emoji-data" */
      /* webpackPrefetch: true */
      "../../emojis.data"
    ).then(({ EMOJIS }) => {
      this.emojiCategories = EMOJIS;
    });

Before upgrading to Angular 18 (which I presume updaed mini-css as a dep), this should have pre-fetched the emoji data before this code executed. Now with Angular 18, the prefetch doesn't happen (as if the prefetch magic comment wasn't there) and the error occurs. In both cases the import still works though.

I wasn't able to create a minimal repro yet - I attempted to recreate this using a fresh Angular 18 project with the webpack builder, but couldn't reproduce the error. I have plans to attempt from the other side - strip down my actual project as much as possible, but I haven't found the time yet.

alexander-akait commented 1 month ago

@Plonq Can you run npm ls webpack and npm ls mini-css-extract-plugin?

Also can you put here - https://github.com/webpack-contrib/mini-css-extract-plugin/blob/master/src/index.js#L904

console.log(chunkMap);
console.log(runtimeRequirements.has(RuntimeGlobals.ensureChunkHandlers));
console.log(withLoading);
console.log(withHmr);
console.log(withPrefetch);
console.log(hasCssMatcher); 
console.log(conditionMap);

and show me values?

It is necessary to understand why the prefetch generated, but the generation of runtime for chunks does not occur, very weird.

alexander-akait commented 1 month ago

I was able to reproduce

alexander-akait commented 1 month ago

Please try - https://github.com/webpack-contrib/mini-css-extract-plugin/releases/tag/v2.9.2

Plonq commented 1 month ago

v2.9.2 seems to fix it. The prefetch is still not working, however I've confirmed that is actually an unrelated, pre-existing issue (likely with webpack).

FWIW, I had to override the version like so:

  "overrides": {
    "@angular-devkit/build-angular": {
      "mini-css-extract-plugin": "2.9.2"
    }
  }

NPM LS:

❯ npm ls mini-css-extract-plugin
REDACTED@0.0.0 /Users/REDACTED
└─┬ @angular-devkit/build-angular@18.2.10 overridden
  └── mini-css-extract-plugin@2.9.2 overridden
❯ npm ls webpack
REDACTED@0.0.0 /Users/REDACTED
├─┬ @angular-devkit/build-angular@18.2.10
│ ├─┬ @angular-devkit/build-webpack@0.1802.10
│ │ └── webpack@5.95.0 deduped
│ ├─┬ @ngtools/webpack@18.2.10
│ │ └── webpack@5.95.0 deduped
│ ├─┬ babel-loader@9.1.3
│ │ └── webpack@5.95.0 deduped
│ ├─┬ copy-webpack-plugin@12.0.2
│ │ └── webpack@5.94.0 deduped
│ ├─┬ css-loader@7.1.2
│ │ └── webpack@5.95.0 deduped
│ ├─┬ less-loader@12.2.0
│ │ └── webpack@5.95.0 deduped
│ ├─┬ mini-css-extract-plugin@2.9.0
│ │ └── webpack@5.94.0 deduped
│ ├─┬ postcss-loader@8.1.1
│ │ └── webpack@5.95.0 deduped
│ ├─┬ sass-loader@16.0.0
│ │ └── webpack@5.95.0 deduped
│ ├─┬ source-map-loader@5.0.0
│ │ └── webpack@5.95.0 deduped
│ ├─┬ webpack-dev-middleware@7.4.2
│ │ └── webpack@5.95.0 deduped
│ ├─┬ webpack-dev-server@5.0.4
│ │ └── webpack@5.95.0 deduped
│ ├─┬ webpack-subresource-integrity@5.1.0
│ │ └── webpack@5.95.0 deduped
│ └─┬ webpack@5.94.0
│   └─┬ terser-webpack-plugin@5.3.10
│     └── webpack@5.95.0 deduped
├─┬ @types/webpack@5.28.5
│ └── webpack@5.95.0
├─┬ copy-webpack-plugin@11.0.0
│ └── webpack@5.95.0 deduped
├─┬ html-webpack-plugin@5.6.0
│ └── webpack@5.95.0 deduped
├─┬ moment-locales-webpack-plugin@1.2.0
│ └── webpack@5.95.0 deduped
└─┬ webpack-shell-plugin-next@2.3.2
  └── webpack@5.95.0 deduped
alexander-akait commented 1 month ago

The prefetch is still not working

That's weird, has this ever worked before? Maybe you can recreate the structure?

michaelfaith commented 1 month ago

Thanks so much for sticking with this issue, even though I wasn't able to put together a repo. Really appreciate it.

Plonq commented 1 month ago

The prefetch is still not working

That's weird, has this ever worked before? Maybe you can recreate the structure?

I'm sure it worked at some point when I first added the magic comment, but it was a while ago so who knows when it stopped working.

Echoing michael, appreciate the responsiveness!