Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack 5 - TypeError: The 'compilation' argument must be an instance of Compilation #631

Closed
owap opened this issue Oct 20, 2020 · 28 comments

Comments

@owap
Copy link

owap commented Oct 20, 2020

  • Operating System: OSX Catalina 10.15.6
  • Node Version: 14.11.0
  • NPM Version: 6.14.8
  • webpack Version: 5.1.3
  • mini-css-extract-plugin Version: 1.1.1

Expected Behavior

  • No Errors when including .scss files
  • .scss files are transformed to css and output in dist directory

Actual Behavior

  • Using MiniCssExtractPlugin.loader results in webpack errors for every .scss file:

"TypeError: The 'compilation' argument must be an instance of Compilation"

image

  • Replacing MiniCssExtractPlugin.loader with 'style-loader' yields no errors and styles the application as intended, but css is not extracted (obviously). This leads me to suspect the issue has something to do with this plugin 🤔

Code

Versions:

"css-loader": "5.0.0",
"html-webpack-plugin": "5.0.0-alpha.6",
"mini-css-extract-plugin": "1.1.1",
"sass-loader": "10.0.3",
"style-loader": "2.0.0",
"webpack": "5.1.3",
"webpack-cli": "4.1.0",

Results in errors:

// weback config
plugins: [
    // ...
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css',
      chunkFilename: '[id].css',
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(s)?css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
      // ...
    ]
  }

No errors, no extract:

// webpack config
 module: {
    rules: [
      {
        test: /\.(s)?css$/i,
        use: ['style-loader', 'css-loader', 'sass-loader'],
      },
      // ...
    ]
  }

Is there anything obvious from this configuration that could yield errors with the compilation argument? Has anybody seen this before? I'm working on creating a small repo to reproduce the issue, but if you see a stupid mistake in here or have clarifying questions for me, please ask right away!

Thanks very much for your help! 👍

@alexander-akait
Copy link
Member

alexander-akait commented Oct 20, 2020

You have two versions of webpack, webpack@4 and webpack@5

@alexander-akait
Copy link
Member

Can you run npm ls webpack?

@owap
Copy link
Author

owap commented Oct 20, 2020

Hi @evilebottnawi, thanks for the quick response!

$ npm ls webpack

@blacksky/[email protected] /Users/apierce/code/work/SSO-UI
└─┬ @blacksky/[email protected]
  └── [email protected]

My application inherits most of its dependencies from our "@blacksky/app" library that we use as a base for most of our webapps. webpack is listed as a dependency (rather than a devDependency) in our "app" library to ensure that all of our applications use the same version of webpack, babel, etc.

I've got a minimal library going trying to reproduce it locally, but so far it imports scss files just fine. Could it have something to do with the fact that we're deriving our dependencies from a child library?

The other thing worth mentioning is that I have an npm run clean script that does the following:

touch node_modules package-lock.json && rm -rf node_modules package-lock.json && npm install

... so I doubt I've got any kind of weird caching going on 🤔

@owap
Copy link
Author

owap commented Oct 20, 2020

A clue!!

When I npm i -DE mini-css-extract-plugin in our application (rather than inherit it from our library), it works fine.

Something about the fact that it's a dependency of another dependency causes it to misbehave... 🤔

@alexander-akait
Copy link
Member

I've got a minimal library going trying to reproduce it locally, but so far it imports scss files just fine. Could it have something to do with the fact that we're deriving our dependencies from a child library?

Yes, maybe you can provide link, will be great to look at structure

@owap
Copy link
Author

owap commented Oct 20, 2020

Looks like MiniExtractCssPlugin works fine as long as I don't npm link to my library. I've got symlinks: false in the resolve section of my webpack config, but it still misbehaves.

I've worked around this issue for now by changing my webpack config to use style-loader in development and MiniCssExtractPlugin in production.

To clarify: MiniCssExtractPlugin works in both development and production modes as long as I don't npm link to the library that lists MiniCssExtractPlugin as a dependency. If I run npm install and then start the app without linking, it works great. If you npm link, you get the compilation TypeErrors

@zy0228
Copy link

zy0228 commented Jan 7, 2021

I get same error, how to resolve

@pmcelhaney
Copy link

I'm getting the same error. The object is an instance of a Compilation. It's just not an instance of the Compilation. Two different copies of the Compilation class are loaded, and even if the code is identical, JS sees two different objects. I ran into a similar problem with LitElement's TemplateResult class recently, which is described here:

https://stackoverflow.com/a/63576099/437

I don't have a solution yet, but hopefully this helps.

@Christian24
Copy link

I've got a minimal library going trying to reproduce it locally, but so far it imports scss files just fine. Could it have something to do with the fact that we're deriving our dependencies from a child library?

Yes, maybe you can provide link, will be great to look at structure

@alexander-akait I am running into the same issue. Are you still looking for a reproduction? I might be able to get something going if you need it still.

@alexander-akait
Copy link
Member

alexander-akait commented Feb 8, 2021

Yep, let's do it and I will look at this

@Christian24
Copy link

Yep, let's do it and I will look at this

There you go: https://github.com/Christian24/mini-css-extract-linking-issue

As always: if you need more info, let me know.

@alexander-akait
Copy link
Member

If you disable html-webpack-plugin all works fine?

@Christian24
Copy link

No, the issue remains the same.

@alexander-akait
Copy link
Member

alexander-akait commented Feb 8, 2021

Yep, here interesting limitation/problem, when you use monorepos and have webpack in root package.json and inside some package, you will have multiple webpack (in node_modules and packages/admin/node_modules and packages/login/node_modules), so instanceof will not work

@alexander-akait
Copy link
Member

alexander-akait commented Feb 8, 2021

Remove webpack from package.json for packages/admin and packages/logic and test it - all works fine

@Christian24
Copy link

Yeah, I have had this issue with multiple plugins already. Most of the time I got it fixed by using the same versions of webpack/webpack-cli.

Interestingly, in webpack@4 this worked fine.

Sadly, we are using Git Submodules (imagine login folder in my example would be its own repository), we check it out in during continous integration (like Jenkins).

So, we need both both webpack dependencies, both in the root repository and in the submodule.

@alexander-akait
Copy link
Member

There is not webpack problems/bugs, this is how instanceof works

More simple, when you have new MiniCssExtractPlugin({filename: "[name].[contenthash].css"})), in packages/config it will use webpack from node_modules, but when you run npm run build it will use webpack from packages/logic, because you create different Compilations instanceof will not work

@alexander-akait
Copy link
Member

alexander-akait commented Feb 8, 2021

You can solve it using --hoist - "postinstall": "lerna bootstrap --hoist", for root package.json https://github.com/lerna/lerna/blob/main/doc/hoist.md

@Christian24
Copy link

I understand.

A few things come to my mind right now:

  • How is sharing configurations in webpack intended? Is it generally discouraged to share configuration/plugins? What I have done from my point of view is relatively nice, since I only need mini-css-extract-plugin once as a dependency in config.
  • This did not happen in webpack@4. What motivated this change? Maybe there is a different way to do this? Or make the error more clear.
  • I do not think hoisting would solve my problem, since it would alter package.json in both login and admin. This is not something we would want, since we would still want to run login and admin independently on CI without checking out the root.
  • I am more wondering if we could remove the webpack dependency from the root and somehow make it use the one in login for example. Or just putting the root into its own folder, next to login and admin.
  • Or maybe remove the instance creation of mini-css-extract-plugin from config to login and admin.
  • Why is this only happening for some plugins?

@alexander-akait
Copy link
Member

Some of the approaches will work, hard to say what is better, because it depends what you need, many developers uses --hoist and it is good for them, but not in your case (as you say).

I am more wondering if we could remove the webpack dependency from the root and somehow make it use the one in login for example. Or just putting the root into its own folder, next to login and admin.

Yes too, you can create helper function like createWebpackConfig and export it from packages/config

Or maybe remove the instance creation of mini-css-extract-plugin from config to login and admin.

Will work

Why is this only happening for some plugins?

Because some plugins require Compilation instance, some of them not

@Christian24
Copy link

First of all, thanks a lot for the explanation.

Yes too, you can create helper function like createWebpackConfig and export it from packages/config

I am not exactly sure I understand what you mean here. Would you have something similar to

module.exports = function() {
    return [loginConfig, adminConfig]
}

in packages/config?

I would very much apreciate if the error message specifically mention having multiple instances of webpack, since it seems lots of people run into this issue on all sorts of plugins.

@alexander-akait
Copy link
Member

You mean you need to require mini-css-extract-plugin inside packages/logic/webpack.config.js, so packages/config can export utils addCSS/addHTML and etc, where you will require it and modify configuration

I would very much apreciate if the error message specifically mention having multiple instances of webpack, since it seems lots of people run into this issue on all sorts of plugins.

Already talking about it

@alexander-akait
Copy link
Member

@Christian24 found solution, how we can solve it, so just wait the next patch release

@Christian24
Copy link

Cool :)

@alexander-akait
Copy link
Member

#698, still WIP, it is not easy, hope I will finish it today/tomorrow

@Christian24
Copy link

Don't worry. I have to focus on other stuff at the moment anyway, so it will probably be a couple days or weeks until I get back to this.

@alexander-akait
Copy link
Member

Fixed, release will be today, should fix all problems with compatibility

@Psychosynthesis
Copy link

Psychosynthesis commented Apr 12, 2021

Hello everybody!

Still have this issue when using Webpack 5 and Next.js.

My package.json deps section:

"dependencies": {
	"@babel/core": "^7.13.0",
	"@googlemaps/markerclustererplus": "^1.0.3",
	"@next/bundle-analyzer": "^9.4.4",
	"@types/dotenv": "^6.1.1",
	"@types/googlemaps": "^3.43.2",
	"@types/lodash.throttle": "^4.1.6",
	"@types/nock": "^10.0.3",
	"@types/node": "^14.0.0",
	"@types/react": "^17.0.0",
	"@types/react-modal": "^3.12.0",
	"@types/react-redux": "^7.0.0",
	"animejs": "^3.2.1",
	"autoprefixer": "^9.6.1",
	"babel-loader": "^8.2.2",
	"babel-plugin-module-resolver": "4.1.0",
	"babel-plugin-transform-define": "^2.0.0",
	"babel-plugin-transform-remove-console": "^6.9.4",
	"babel-preset-react-app": "^10.0.0",
	"clsx": "^1.1.1",
	"cross-env": "^5.2.1",
	"css-loader": "^5.2.0",
	"dotenv": "^8.1.0",
	"eslint": "^7.19.0",
	"file-loader": "6.2.0",
	"isomorphic-unfetch": "^3.0.0",
	"lodash.throttle": "^4.1.1",
	"mini-css-extract-plugin": "^1.4.x",
	"next": "^10.1.0",
	"next-compose-plugins": "^2.2.0",
	"next-images": "^1.7.0",
	"next-seo": "^4.19.0",
	"query-string": "^6.13.8",
	"react": "^17.0.1",
	"react-dom": "^17.0.1",
	"react-modal": "^3.12.1",
	"react-redux": "^7.2.3",
	"redux": "^4.0.5",
	"redux-devtools-extension": "^2.13.8",
	"redux-thunk": "^2.3.0",
	"sass": "^1.32.x",
	"sass-loader": "^10.0.0",
	"style-loader": "^2.0.0",
	"svg-sprite-loader": "^6.x.x",
	"swiper": "^6.4.10",
	"ts-loader": "^8.0.15",
	"ts-node": "^9.1.1",
	"typescript": "^4.2.0",
	"webpack": "^5.x.x"
},

Webpack config that causes this error:

config.module.rules.push({
	test: new RegExp(`\\.+(scss|sass)$`),
	use: [
		(dev && !isServer) && 'style-loader',
		!dev && {
			loader: MiniCssExtractPlugin.loader,
			options: {
				publicPath: path.resolve(__dirname, 'public/static/css'),
			},
		},
		{ loader: 'css-loader', options: { sourceMap: dev }, },
		{
			loader: 'sass-loader',
			options: {
				sassOptions: {
					includePaths: [
						path.resolve(__dirname, 'public/static/css'),
						path.resolve(__dirname, 'src'),
						path.resolve(__dirname, 'pages')
					]
				},
				sourceMap: dev,
			}
		},
	].filter(Boolean)
});

I cannot remove the webpack from the dependencies - after that, both next build and nodemon (npm run dev runs it for us) stop working for me.

If I install the 4th webpack everything works fine, but we have a goal to update the webpack... but because of this error, the mini-css-extract-plugin prevents us from doing this ...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants