TypeError: MiniCssExtractPlugin is not a constructor

[webpack-cli] TypeError: MiniCssExtractPlugin is not a constructor at module.exports (/home/andrey/smartadmin-app/webpack.config.js:70:9) at loadConfigByPath (/home/andrey/smartadmin-app/node_modules/webpack-cli/lib/webpack-cli.js:1745:27) at async WebpackCLI.loadConfig (/home/andrey/smartadmin-app/node_modules/webpack-cli/lib/webpack-cli.js:1830:30) at async WebpackCLI.createCompiler (/home/andrey/smartadmin-app/node_modules/webpack-cli/lib/webpack-cli.js:2185:18) at async Command.<anonymous> (/home/andrey/smartadmin-app/node_modules/@webpack-cli/serve/lib/index.js:98:30) at async Promise.all (index 1) at async Command.<anonymous> (/home/andrey/smartadmin-app/node_modules/webpack-cli/lib/webpack-cli.js:1672:7)

I have got this error and don't understand why it happens. I didn't change any package version and have just done npm install, and I was broken.

{ "name": "react-typescript", "version": "1.0.0", "main": "index.js", "license": "MIT", "scripts": { "view-file": "ts-node --project ts.node.config.json ./webpack/createViewFile.ts", "build-dev": "webpack --env mode=development && npm run build-storybook", "build-dev-server": "webpack --env mode=development", "build-prod": "webpack --env mode=production", "lint": "eslint 'client/**'", "storybook": "start-storybook -p 5000", "build-storybook": "build-storybook -o ./public/storybook", "start": "webpack serve --open" }, "dependencies": { "axios": "0.24.0", "clsx": "1.1.1", "dotenv": "8.6.0", "react": "17.0.2", "react-dom": "17.0.2", "react-hook-form": "7.19.5", "react-router-dom": "6.0.2", "react-string-replace": "0.4.4", "webpack-cli": "4.9.1" }, "devDependencies": { "@babel/core": "7.16.0", "@storybook/addon-actions": "6.4.0-rc.2", "@storybook/addon-docs": "6.4.0-rc.2", "@storybook/addon-essentials": "6.4.0-rc.2", "@storybook/addon-links": "6.4.0-rc.2", "@storybook/builder-webpack5": "6.4.0-rc.2", "@storybook/manager-webpack5": "6.4.0-rc.2", "@storybook/preset-scss": "1.0.3", "@storybook/react": "6.4.0-rc.2", "@types/express": "4.17.13", "@types/node": "16.11.7", "@types/react": "17.0.33", "@types/react-dom": "17.0.10", "@typescript-eslint/eslint-plugin": "5.2.0", "@typescript-eslint/parser": "5.2.0", "babel-loader": "8.2.3", "clean-webpack-plugin": "4.0.0", "compression-webpack-plugin": "9.0.0", "copy-webpack-plugin": "9.1.0", "css-loader": "6.5.1", "eslint": "7.32.0", "eslint-config-airbnb": "18.2.1", "eslint-config-prettier": "8.3.0", "eslint-plugin-import": "2.25.2", "eslint-plugin-jsx-a11y": "6.4.1", "eslint-plugin-prettier": "4.0.0", "eslint-plugin-react": "7.26.1", "eslint-plugin-react-hooks": "1.7.0", "html-webpack-plugin": "5.5.0", "mini-css-extract-plugin": "2.4.4", "prettier": "2.4.1", "sass": "1.43.4", "sass-loader": "12.3.0", "style-loader": "3.3.1", "terser-webpack-plugin": "5.2.4", "ts-loader": "9.2.6", "ts-node": "10.4.0", "typescript": "4.4.4", "webpack": "5.64.1", "webpack-dev-server": "4.7.3", "webpack-manifest-plugin": "4.1.1", "webpack-nano": "1.1.1" }
}

The command which I execute is npm run start, and my webpack.config.js file is:

require('dotenv').config();
const TerserPlugin = require('terser-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const CopyPlugin = require('copy-webpack-plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const { execSync } = require('child_process');
const rules = require('./webpack/rules');
const paths = require('./webpack/paths');
const enviroment = require('./webpack/env');
module.exports = (env) => { const isProduction = env.mode === enviroment.PRODUCTION; const isDevServer = !!env.WEBPACK_SERVE; if (isDevServer) { return { watch: true, mode: enviroment.DEVELOPMENT, entry: './src/index.tsx', stats: { errorDetails: true, }, module: { rules: [rules.ts(), rules.css()], }, resolve: { extensions: ['.tsx', '.ts', '.js'], modules: ['node_modules', 'src'], }, output: { filename: 'main.js', path: paths.public, publicPath: paths.public, }, devServer: { port: 8080, host: 'localhost', static: [paths.public], compress: true, hot: true, headers: { 'Access-Control-Allow-Origin': '*', }, historyApiFallback: { index: '/index.html', }, client: { overlay: true, logging: 'info', progress: true, }, devMiddleware: { writeToDisk: true, }, }, plugins: [ { apply(compiler) { compiler.hooks.environment.tap('removePublicFolder', () => { execSync('rm -rf public'); }); }, }, new CompressionPlugin(), new MiniCssExtractPlugin({ filename: isDevServer ? 'main.css' : '[name].[hash].css', ignoreOrder: true, }), new webpack.DefinePlugin({ 'process.env': JSON.stringify(process.env), }), new WebpackManifestPlugin({ publicPath: '', }), new CopyPlugin({ patterns: [ { from: paths.views, to: paths.public }, { from: paths.static, to: paths.public }, ], }), ], }; } return { mode: env.mode, entry: './src/index.tsx', stats: { errorDetails: true, }, ...(isProduction && { optimization: { minimize: true, splitChunks: { cacheGroups: { vendor: { test: /[\\/]node_modules[\\/]/, name: 'vendor', chunks: 'all', }, }, }, minimizer: [ new TerserPlugin({ extractComments: false, }), ], }, }), module: { rules: [rules.ts(), rules.css()], }, resolve: { extensions: ['.tsx', '.ts', '.js'], modules: ['node_modules', 'src'], }, output: { filename: '[name].[contenthash].js', path: paths.public, publicPath: '/', }, plugins: [ { apply(compiler) { compiler.hooks.environment.tap('removePublicFolder', () => { execSync('rm -rf public'); }); }, }, new CompressionPlugin(), new MiniCssExtractPlugin({ filename: isDevServer ? 'main.css' : '[name].[hash].css', ignoreOrder: true, }), new webpack.DefinePlugin({ 'process.env': JSON.stringify(process.env), }), new WebpackManifestPlugin({ publicPath: '', }), { apply(compiler) { compiler.hooks.done.tap('done', () => { execSync('npm run view-file'); execSync('ls'); }); }, }, new CopyPlugin({ patterns: [{ from: paths.static, to: paths.public }], }), ], };
};

Also I will attach ./webpack/rules.js, to make it clearer:

const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const paths = require('./paths');
const css = () => { return { test: /\.scss$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader', options: { modules: true, }, }, { loader: 'sass-loader', options: { sassOptions: { indentWidth: 4, includePaths: [paths.styles], }, }, }, ], };
};
const ts = () => { return { test: /\.tsx?$/, exclude: /node_modules/, use: [ { loader: 'ts-loader', options: { configFile: 'tsconfig.json', }, }, ], };
};
module.exports = { ts, css,
};
4

4 Answers

There is an open issue for this on the create-react-app repository. It looks like this comment has a temporary fix of adding the following to file package.json:

The below works if you're using Yarn:

"resolutions": { "mini-css-extract-plugin": "2.4.5"
},

Use the command below for npm:

npm i -D --save-exact mini-css-extract-plugin@2.4.5

Update: As of January 17, it appears that this issue is fixed by mini-css-extract-plugin v2.5.1. You should be able to remove the version pin created above and npm i or yarn install to update.

5

For me it was working too and after an update it just stopped working, but as the error suggests, the constructor is undefined, so I changed the way the plugin was called and it worked.

Add '.default' in the call as below:

const MiniCssExtractPlugin = require("mini-css-extract-plugin").default;
1

As suggested by Macedo_Montalvão and Sharpek:

You can go to your React project folder.

Then head over to this path:

node_modules\react-scripts\config

Open the webpack.config.js file.

Replace

const MiniCssExtractPlugin = require('mini-css-extract-plugin');

with

const MiniCssExtractPlugin = require('mini-css-extract-plugin').default;

This should work.

1

There are breaking changes in this plugin (I think this was by mistake). Here you can read more about this:

The best solution is to change import linked as Macedo_Montalvão said.

const MiniCssExtractPlugin = require("mini-css-extract-plugin").default;

This error was fixed in version 2.5.1.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like