Skip to content

Using Webpack 4 throws an Unhandled rejection TypeError #9

@a1isaeed

Description

@a1isaeed

This plugin works great with Webpack v3, but after I upgraded to Webpack v4, I can no longer build.

The Error

The error I see in the console is:

Unhandled rejection TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string or an instance of Buffer or URL. Received undefined
    at Object.stat (fs.js:920:10)
    at /Users/ali/Developer/playground/only-if-changed/node_modules/only-if-changed-webpack-plugin/mtime.js:7:8
    at /Users/ali/Developer/playground/only-if-changed/node_modules/async/lib/async.js:181:20
    at replenish (/Users/ali/Developer/playground/only-if-changed/node_modules/async/lib/async.js:319:21)
    at /Users/ali/Developer/playground/only-if-changed/node_modules/async/lib/async.js:330:15
    at Object.async.forEachLimit.async.eachLimit (/Users/ali/Developer/playground/only-if-changed/node_modules/async/lib/async.js:220:35)
    at Object.getFilesMtimes (/Users/ali/Developer/playground/only-if-changed/node_modules/only-if-changed-webpack-plugin/mtime.js:6:9)
    at OnlyIfChangedPlugin.updateDependenciesMtimes (/Users/ali/Developer/playground/only-if-changed/node_modules/only-if-changed-webpack-plugin/index.js:34:9)
    at /Users/ali/Developer/playground/only-if-changed/node_modules/only-if-changed-webpack-plugin/index.js:125:19
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/ali/Developer/playground/only-if-changed/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:5:1)
    at AsyncSeriesHook.lazyCompileHook (/Users/ali/Developer/playground/only-if-changed/node_modules/tapable/lib/Hook.js:154:20)
    at /Users/ali/Developer/playground/only-if-changed/node_modules/webpack/lib/Compiler.js:467:30
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/ali/Developer/playground/only-if-changed/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook (/Users/ali/Developer/playground/only-if-changed/node_modules/tapable/lib/Hook.js:154:20)
    at /Users/ali/Developer/playground/only-if-changed/node_modules/webpack/lib/Compilation.js:957:35
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/Users/ali/Developer/playground/only-if-changed/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook (/Users/ali/Developer/playground/only-if-changed/node_modules/tapable/lib/Hook.js:154:20)
    at /Users/ali/Developer/playground/only-if-changed/node_modules/webpack/lib/Compilation.js:948:32
    at eval (eval at create (/Users/ali/Developer/playground/only-if-changed/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:14:1)
    at /Users/ali/Developer/playground/only-if-changed/node_modules/uglifyjs-webpack-plugin/dist/index.js:287:11
    at step (/Users/ali/Developer/playground/only-if-changed/node_modules/uglifyjs-webpack-plugin/dist/uglify/Runner.js:94:11)
    at done (/Users/ali/Developer/playground/only-if-changed/node_modules/uglifyjs-webpack-plugin/dist/uglify/Runner.js:103:22)
    at tryCatcher (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/util.js:16:23)
    at Promise._settlePromiseFromHandler (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:547:31)
    at Promise._settlePromise (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:604:18)
    at Promise._settlePromise0 (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:729:18)
    at Promise._fulfill (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:673:18)
    at Promise._resolveCallback (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:466:57)
    at Promise._settlePromiseFromHandler (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:559:17)
    at Promise._settlePromise (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:604:18)
    at Promise._settlePromise0 (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:649:10)
    at Promise._settlePromises (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:729:18)
    at Promise._fulfill (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:673:18)
    at Promise._resolveCallback (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:466:57)
    at Promise._settlePromiseFromHandler (/Users/ali/Developer/playground/only-if-changed/node_modules/bluebird/js/release/promise.js:559:17)

Root Cause

Webpack v3 used to return an array of strings for compilation.fileDependencies in index.js:L123, but Webpack v4 returns a Set instead:

  compiler.plugin('after-compile', function(compilation, afterCompileDone) {
    // get updated mtimes of file dependencies of compilation
    pluginContext.updateDependenciesMtimes(compilation.fileDependencies, afterCompileDone);
  });

Logging compilation.fileDependencies to the console returns:

=== Webpack v3 ===
[                                                        
  '/Users/ali/Developer/playground/only-if-changed/app.js',
  '/Users/ali/Developer/playground/only-if-changed/helpers.js'
]

=== Webpack v4 ===
   SortableSet(2) [Set] {              
    '/Users/ali/Developer/playground/only-if-changed/app.js',
    '/Users/ali/Developer/playground/only-if-changed/helpers.js',
    _sortFn: undefined,
    _lastActiveSortFn: undefined,
    _cache: undefined,
    _cacheOrderIndependent: undefined
  }

This causes issues down the line in mtime.js:L6 when we try to iterate on files expecting it to be an array.

Solution

One quick fix is to convert the Set to an Array using Array.from(:

  compiler.plugin('after-compile', function(compilation, afterCompileDone) {
    // get updated mtimes of file dependencies of compilation
    pluginContext.updateDependenciesMtimes(Array.from(compilation.fileDependencies), afterCompileDone);
  });

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions