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

Callback was already called #11

Closed
eulbot opened this issue Mar 13, 2018 · 14 comments · Fixed by #12
Closed

Callback was already called #11

eulbot opened this issue Mar 13, 2018 · 14 comments · Fixed by #12

Comments

@eulbot
Copy link

eulbot commented Mar 13, 2018

After updating to 3.0.0, I get an Callback was already called error. I reverted back to 1.4.0 and it runs again without issues.

Here is the callstack:

Error: Callback was already called.
    at throwError ([PATH]\node_modules\neo-async\async.js:14:11)
    at [PATH]\node_modules\neo-async\async.js:6725:13
    at normalResolver.resolve ([PATH]\node_modules\webpack\lib\NormalModuleFactory.js:188:25)
    at doResolve ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:181:12)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn0 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:15:1)
    at resolver.doResolve ([PATH]\node_modules\enhanced-resolve\lib\UnsafeCachePlugin.js:37:5)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn0 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:15:1)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn1 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:24:1)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn43 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:399:1)
    at resolver.doResolve ([PATH]\node_modules\enhanced-resolve\lib\ModuleKindPlugin.js:23:37)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn0 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:15:1)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn0 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:15:1)
    at args ([PATH]\node_modules\enhanced-resolve\lib\forEachBail.js:30:14)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn0 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:15:1)
    at resolver.doResolve ([PATH]\node_modules\enhanced-resolve\lib\UnsafeCachePlugin.js:37:5)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn0 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:15:1)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn1 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:24:1)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn44 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:411:1)
    at hook.callAsync ([PATH]\node_modules\enhanced-resolve\lib\Resolver.js:232:5)
    at _fn1 (eval at create ([PATH]\node_modules\tapable\lib\HookCodeFactory.js:24:12), <anonymous>:24:1)
@jonaskello
Copy link
Member

The example config in this repo works with webpack 4 without issues. In order to help you we would need to know what is different in your config. Could you post a webpack.config.js to reproduce the error you are getting?

@jonaskello
Copy link
Member

jonaskello commented Mar 13, 2018

Also are you using webpack 3 or webpack 4? Version 3.0.0 of this plugin should work with both.

@eulbot
Copy link
Author

eulbot commented Mar 13, 2018

That's my config (I'm using webpack 4)

const webpack = require('webpack');
const path = require('path');
const tsconfig = path.join(__dirname, '../moduleA/tsconfig.json');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

var config = {
    entry: [
        '../moduleA/app/app.ts'
    ],
    output: {
        filename: 'moduleA.app.js',
        path: path.join(__dirname, '../moduleA/scripts')
    },
    mode: 'development',
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
        plugins: [
            new TsconfigPathsPlugin({
                configFile: tsconfig,
                logLevel: 'info',
                extensions: ['.tsx', '.ts', '.js']
            })
        ]
    },
    module: {
        rules: [
            {
                test: /\.ts$/,
                loader: 'ts-loader',
                options: {
                    logInfoToStdOut: true,
                    logLevel: 'info',
                    configFile: tsconfig,
                    compilerOptions: {
                        noEmit: false,
                        sourceMap: true
                    }
                }
            }
        ]
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            ko: "knockout",
            "ko.validation": "knockout.validation"
        })
    ],
    devtool: "source-map"
};

module.exports = config;

And these are my global modules:

+-- gulp@3.9.1
+-- gulp-concat@2.6.1
+-- gulp-json-modify@1.0.2
+-- gulp-plumber@1.2.0
+-- gulp-util@3.0.8
+-- lodash@4.17.5
+-- ts-loader@4.0.1
+-- tsconfig-paths-webpack-plugin@1.4.0
+-- uglify-js@2.8.29
+-- webpack@4.1.1
`-- webpack-cli@2.0.10

And here is the tsconfig that's used for the build:

{
  "compileOnSave": true,
  "compilerOptions": {
    "baseUrl": ".",
    "experimentalDecorators": true,
    "lib": [ "es2016", "dom", "es2015.promise" ],
    "moduleResolution": "node",
    "noEmit": true,
    "noImplicitAny": false,
    "paths": {
      "moduleA/*": [ "../moduleA/*" ],
      "moduleC/*": [ "../moduleC/*" ],
      "moduleD/*": [ "../moduleD/*" ],
      "moduleE/*": [ "../moduleE/*" ],
      "moduleF/*": [ "../moduleF/*" ],
      "*": [ "../ModuleB/node_modules/*" ]
    },
    "sourceMap": true,
    "target": "es6",
    "typeRoots": [
      "../ModuleB/node_modules/@types"
    ]
  },
  "exclude": [
    "node_modules",
    "dist",
    "Release",
    "obj"
  ],
  "include": [
    "**/*.ts",
    "../ModuleB/node_modules/@types",
    "../ModuleB/node_modules/"
  ]
}

@Nayni
Copy link
Contributor

Nayni commented Mar 13, 2018

Maybe it's because this https://github.com/dividab/tsconfig-paths-webpack-plugin/blob/master/src/plugin.ts#L281 isn't 100% correct anymore with Webpack 4.

This seems like the most likely reason why the callback was already called.

Might have to-do something like this:

        return (resolver.doResolve as doResolve)(
          hook,
          newRequest,
          `Resolved request '${innerRequest}' to '${foundMatch}' using tsconfig.json paths mapping`,
          createInnerContext({ ...resolveContext }),
          (err2: Error, result2: string): void => {
            if (arguments.length > 0) {
              return callback(err2, result2);
            } else {
              return callback();
            }
          }
        );

That's how enhanced-resolve seems to be doing it too. Probably worth seeing if that fixed the issue. Maybe a good idea for @eulbot to try this out on your setup and see if that solves the issue?

@jonaskello
Copy link
Member

jonaskello commented Mar 13, 2018

@Nayni I think you may be on to something. The code for this plugin was mostly setup from the path plugin in awsome typescript loader, and I think the code in that plugin mostly came from the alias plugin. Both of which was using the old plugin system.

I looked at the current code for the alias plugin and it seems the same line still exists (at least it is the same comment :-)). However I'm not sure if that code is updated to the new plugin system.

@Nayni
Copy link
Contributor

Nayni commented Mar 13, 2018

In the code you linked, you can also see that it only invokes 1 callback. While the code in this plugin actually has a chance to fire the callback twice, which I think is not allowed anymore in the new plugin system (while it might've worked in the old system before Webpack 4).

I think it's best to adjust the code to how I posted and only callback with nothing (or null twice) when we don't have any error or result. That way the callback will never fire twice.

I wasn't aware of this either, sadly the new API is not documented well yet.

@jonaskello
Copy link
Member

@Nayni Aha, ok I think I understand what you mean now. Would you like to do a PR for the changes you proposed?

@Nayni
Copy link
Contributor

Nayni commented Mar 13, 2018

I'm currently at my day job, but I'd be happy to see if I can reproduce the callback firing twice and drop a PR later today.

@Nayni
Copy link
Contributor

Nayni commented Mar 13, 2018

Hopefully my PR can solve the issue.

I also see that https://github.com/dividab/tsconfig-paths/blob/master/src/match-path-async.ts#L123 is not returning after doing it's doneCallback which could also be the cause of this issue as the plugin is using the Async version to match path, and by not returning it will recurse further and call the same callback later (which is what I also fixed in my PR but just for the plugin itself).

And knowing that with a previous version it just works, this is actually more likely.

EDIT: Also made a PR for that in tsconfig-paths: dividab/tsconfig-paths#29 Probably best to combine both of them.

@jonaskello
Copy link
Member

The fix for this is now released in v3.0.1. @eulbot Please give it a try.

@Nayni
Copy link
Contributor

Nayni commented Mar 13, 2018

Probably going to need dividab/tsconfig-paths#30 to be merged in. Async code is a b*tch :)

I acutally found a reproduction path with the example from the repo as well: https://github.com/Nayni/tsconfig-paths-webpack-plugin/blob/example-with-node-modules-fallback/example/
The catch was to have a * fallthrough that should be resolved by node_modules

@jonaskello
Copy link
Member

I released 3.0.2 that includes the above fix from tsconfig-paths.

@jonaskello
Copy link
Member

I'll re-open this until @eulbot confirms it is working for his case.

@jonaskello jonaskello reopened this Mar 14, 2018
@eulbot
Copy link
Author

eulbot commented Mar 14, 2018

Build completed in 78.928s

Hash: ee6746c13f9feb58029c
Version: webpack 4.1.1
Child
    Hash: ee6746c13f9feb58029c
    Time: 78935ms
    Built at: 2018-3-14 11:47:23

I can confirm that it's working with 3.0.2. Thank you all for your quick help.

@eulbot eulbot closed this as completed Mar 14, 2018
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

Successfully merging a pull request may close this issue.

3 participants