Running webpack throws 'Callback was already called' error

Viewed 8788

I just started learning webpack to manage dependencies in my project. I am trying to use it to build bundles for my typescript and javascript files. For the typescript files, I am using the ts-loader plugin for handling it. For CSS, I am using the mini-css-extract and an optimize-css-assets plugin. When I try to run webpack, I get the following error and I am not able to figure out what might be causing this error.

user@system spl % npm run build

> spl@1.0.0 build /Users/user/Downloads/spl
> webpack --config webpack.config.js

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

Error: Callback was already called.
    at throwError (/Users/user/Downloads/spl/node_modules/neo-async/async.js:16:11)
    at /Users/user/Downloads/spl/node_modules/neo-async/async.js:2818:7
    at processTicksAndRejections (internal/process/task_queues.js:79:11)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! spl@1.0.0 build: `webpack --config webpack.config.js`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the spl@1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/user/.npm/_logs/2020-05-14T14_23_32_985Z-debug.log

The following is my webpack.config file that I am using to build my dist files.

const path = require('path');

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require("optimize-css-assets-webpack-plugin");

module.exports = {
    mode: 'production',
    entry: "./static/js/index.js",
    output: {
        filename: "bundle.[contentHash].js",  // File name with hash, based on content
        path: path.resolve(__dirname, 'dist')
    },
    optimization: {
        minimizer: [
            new OptimizeCssAssetsPlugin(),
            new TerserPlugin(),
            new HtmlWebpackPlugin({
                template: "./static/index.html",
                minify: {
                    removeAttributeQuotes: true,
                    collapseWhitespace: true,
                    removeComments: true
                }
            })
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "[name].[contentHash].css"
        }),
        new CleanWebpackPlugin(),
    ],
    module: {
        rules: [
            {
                test: /\.html$/,
                use: [ "html-loader" ]
            },
            {
                test: /\.[tj]s$/,
                use: "ts-loader",
                exclude: /(node_modules|tests)/
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader"
                ]
            }
        ],
    },
    resolve: {
        alias: {
            src: path.resolve(__dirname, 'src'),
            static: path.resolve(__dirname, 'static'),
        },
        extensions: [ '.ts', '.js' ]
    }
}
5 Answers

I had the same issue and I realized that I was importing CSS file from my index.html file:

<link rel="stylesheet" href="./css/main.css">

although the CSS file should have been imported from entry file (index.js) using import:

import '../css/main.css'; 

so I deleted the line <link rel="stylesheet" href="./css/main.css"> and solved the problem. You can see your HTML file and check if there are any assets imported from your HTML file. I hope it helped.

tl;dr: Upgrading webpack to a newer version solved it for me.

I went into node_modules/neo-async/async.js and modified the onlyOnce so that it gives a bit more descriptive stack trace like this:

  /**
   * @private
   * @param {Function} func
   */
  function onlyOnce(func) {
    const defined = new Error('onlyOnce first used here')
    return function(err, res) {
      var fn = func;
      func = () => {
        console.error(defined);
        throwError();
      };
      fn(err, res);
    };
  }

The stack trace points into webpack’s internal code, which, when I upgraded to the latest version, solves this issue.

I ran into this issue and was able to determine that the cause was circular dependencies in Typescript, not outdated dependencies as suggested by other answers here. This error appeared when I refactored code from import MyClass from "folder/file" into import { MyClass } from "folder".

I only considered this possibility after reading this post about differences in semantics between export default and other types of exports.

I had this issue and it was related to a recent downgrade someone had made to mini-css-extract-plugin. We are using pnpm, so this answer is specific to that. I had to delete the pnpm-lock.yaml file in the module I was trying to run out of spring boot dashboard in VSCode. This file is generated if it is missing, but for us anyway, it was committed to the repo. If that doesn't work for you, you might also consider deleting the npm-cache and .pnpm-store dirs. The locations of those files are configured in the .npmrc file in your user's home directory.

For me, the issue came after upgrading css-loader. Downgrading it back to the original version did the trick for me

diff --git a/package.json b/package.json
index 7151c509..b0eba48b 100644
--- a/package.json
+++ b/package.json
@@ -111,7 +111,7 @@
     "webpack-merge": "^4.1.3"
   },
   "devDependencies": {
-    "css-loader": "^6.5.1",
+    "css-loader": "^1.0.0",
Related