assets-webpack-plugin: Broken output (error in mkdirp() of createOutputWriter.js)

As of version 3.6.1 there is an error thrown when using this plugin in a webpack configuration running a gulp task with the help of webpack-stream. Here some information about my setup:

// package.json
"assets-webpack-plugin": "3.6.1",
"gulp": "4.0.0",
"webpack": "4.12.0",
"webpack-cli": "3.0.6",
"webpack-merge": "4.1.3",
"webpack-stream": "4.0.3",
// and some more packages ...
// gulpfile.js
const gulp = require('gulp');
const webpackStream = require('webpack-stream');
const webpack = require('webpack');
const webpackDevConfig = require('./webpack.dev.config');
const webpackProdConfig = require('./webpack.prod.config');

// some different code ...

gulp.task('bundle', () => {
  const webpackConfig = isProduction ? webpackProdConfig : webpackDevConfig;
  return gulp.src('./frontend/app.js')
    .pipe(webpackStream(webpackConfig, webpack))
    .pipe(gulp.dest(options.targetFolder));
});

And here the error:

Error in plugin "webpack-stream"
Message:
    invalid argument
Details:
    domain: [object Object]
    domainThrown: true

The error isn’t helpful at all, so I started debugging. First I enabled the showStack flag in /node_modules/plugin-error/index.js. After that, the following stack trace is displayed:

Error
    at /home/xxx/node_modules/webpack-stream/index.js:146:32
    at finalCallback (/home/xxx/node_modules/webpack/lib/Compiler.js:157:39)
    at hooks.done.callAsync.err (/home/xxx/node_modules/webpack/lib/Compiler.js:206:14)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/xxx/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:6:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/home/xxx/node_modules/webpack/node_modules/tapable/lib/Hook.js:35:21)
    at emitRecords.err (/home/xxx/node_modules/webpack/lib/Compiler.js:204:22)
    at Compiler.emitRecords (/home/xxx/node_modules/webpack/lib/Compiler.js:319:39)
    at emitAssets.err (/home/xxx/node_modules/webpack/lib/Compiler.js:198:10)
    at hooks.afterEmit.callAsync.err (/home/xxx/node_modules/webpack/lib/Compiler.js:305:14)
    at _err1 (eval at create (/home/xxx/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:16:1)
    at /home/xxx/node_modules/webpack-stream/index.js:192:9
    at _err0 (eval at create (/home/xxx/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:12:1)
    at /home/xxx/node_modules/assets-webpack-plugin/index.js:125:9
    at /home/xxx/node_modules/assets-webpack-plugin/lib/output/createQueuedWriter.js:14:7
    at /home/xxx/node_modules/assets-webpack-plugin/lib/output/createOutputWriter.js:19:16
    at Immediate._onImmediate (/home/xxx/node_modules/memory-fs/lib/MemoryFileSystem.js:282:5)

Then I stumbled upon https://github.com/kossnocorp/assets-webpack-plugin/pull/90. Those changes were introduced with 3.6.1. So I tried the previous version 3.6.0 which worked without throwing an error.

In a next step I thought it would be useful to get some information about the data around the mkdirp() call. I added the following lines lib/output/createOutputWriter.js.

mkdirp(options.path, function (err) {
  console.log('options', options);
  console.log('fs', fs);
  console.log('err', err);
  // ...

Using version 3.6.0 the following is displayed afterwards:

options { path: '.',
  filename: 'webpack-assets.json',
  prettyPrint: false,
  update: false,
  fullPath: true,
  processOutput: [Function] }
fs { constants: 
   { O_RDONLY: 0,
     O_WRONLY: 1,
     O_RDWR: 2,
     S_IFMT: 61440,
     S_IFREG: 32768,
     S_IFDIR: 16384,
     S_IFCHR: 8192,
     S_IFBLK: 24576,
     S_IFIFO: 4096,
     S_IFLNK: 40960,
     S_IFSOCK: 49152,
     O_CREAT: 64,
     O_EXCL: 128,
     O_NOCTTY: 256,
     O_TRUNC: 512,
     O_APPEND: 1024,
     O_DIRECTORY: 65536,
     O_NOATIME: 262144,
     O_NOFOLLOW: 131072,
     O_SYNC: 1052672,
     O_DSYNC: 4096,
     O_DIRECT: 16384,
     O_NONBLOCK: 2048,
     S_IRWXU: 448,
     S_IRUSR: 256,
     S_IWUSR: 128,
     S_IXUSR: 64,
     S_IRWXG: 56,
     S_IRGRP: 32,
     S_IWGRP: 16,
     S_IXGRP: 8,
     S_IRWXO: 7,
     S_IROTH: 4,
     S_IWOTH: 2,
     S_IXOTH: 1,
     F_OK: 0,
     R_OK: 4,
     W_OK: 2,
     X_OK: 1,
     UV_FS_COPYFILE_EXCL: 1,
     COPYFILE_EXCL: 1 },
  Stats: [Function: Stats],
  F_OK: 0,
  R_OK: 4,
  W_OK: 2,
  X_OK: 1,
  access: [Function],
  accessSync: [Function],
  exists: [Function],
  existsSync: [Function],
  readFile: [Function],
  readFileSync: [Function],
  close: [Function],
  closeSync: [Function],
  open: [Function],
  openSync: [Function],
  read: [Function],
  readSync: [Function],
  write: [Function],
  writeSync: [Function],
  rename: [Function],
  renameSync: [Function],
  truncate: [Function],
  truncateSync: [Function],
  ftruncate: [Function],
  ftruncateSync: [Function],
  rmdir: [Function],
  rmdirSync: [Function],
  fdatasync: [Function],
  fdatasyncSync: [Function],
  fsync: [Function],
  fsyncSync: [Function],
  mkdir: [Function],
  mkdirSync: [Function],
  readdir: [Function],
  readdirSync: [Function],
  fstat: [Function],
  lstat: [Function],
  stat: [Function],
  fstatSync: [Function],
  lstatSync: [Function],
  statSync: [Function],
  readlink: [Function],
  readlinkSync: [Function],
  symlink: [Function],
  symlinkSync: [Function],
  link: [Function],
  linkSync: [Function],
  unlink: [Function],
  unlinkSync: [Function],
  fchmod: [Function],
  fchmodSync: [Function],
  chmod: [Function],
  chmodSync: [Function],
  fchown: [Function],
  fchownSync: [Function],
  chown: [Function],
  chownSync: [Function],
  _toUnixTimestamp: [Function: toUnixTimestamp],
  utimes: [Function],
  utimesSync: [Function],
  futimes: [Function],
  futimesSync: [Function],
  writeFile: [Function],
  writeFileSync: [Function],
  appendFile: [Function],
  appendFileSync: [Function],
  watch: [Function],
  watchFile: [Function],
  unwatchFile: [Function],
  realpathSync: [Function: realpathSync],
  realpath: [Function: realpath],
  mkdtemp: [Function],
  mkdtempSync: [Function],
  copyFile: [Function],
  copyFileSync: [Function],
  createReadStream: [Function],
  ReadStream: 
   { [Function: ReadStream]
     super_: 
      { [Function: Readable]
        ReadableState: [Function: ReadableState],
        super_: [Object],
        _fromList: [Function: fromList] } },
  FileReadStream: 
   { [Function: ReadStream]
     super_: 
      { [Function: Readable]
        ReadableState: [Function: ReadableState],
        super_: [Object],
        _fromList: [Function: fromList] } },
  createWriteStream: [Function],
  WriteStream: 
   { [Function: WriteStream]
     super_: { [Function: Writable] WritableState: [Function: WritableState], super_: [Object] } },
  FileWriteStream: 
   { [Function: WriteStream]
     super_: { [Function: Writable] WritableState: [Function: WritableState], super_: [Object] } } }
err null

But using version 3.6.1 the output is different:

options { path: '.',
  filename: 'webpack-assets.json',
  prettyPrint: false,
  update: false,
  fullPath: true,
  processOutput: [Function] }
fs MemoryFileSystem { data: { home: { '': true, 'xxx': [Object] } } }
err { Error: invalid argument
    at pathToArray (/home/xxx/node_modules/memory-fs/lib/MemoryFileSystem.js:44:10)
    at MemoryFileSystem.mkdirpSync (/home/xxx/node_modules/memory-fs/lib/MemoryFileSystem.js:139:13)
    at MemoryFileSystem.(anonymous function) [as mkdirp] (/home/xxx/node_modules/memory-fs/lib/MemoryFileSystem.js:279:34)
    at writeOutput (/home/xxx/node_modules/assets-webpack-plugin/lib/output/createOutputWriter.js:17:8)
    at AssetsWebpackPlugin.queuedWriter [as writer] (/home/xxx/node_modules/assets-webpack-plugin/lib/output/createQueuedWriter.js:29:7)
    at afterEmit (/home/xxx/node_modules/assets-webpack-plugin/index.js:121:12)
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/home/xxx/node_modules/webpack/node_modules/tapable/lib/HookCodeFactory.js:24:12), <anonymous>:7:1)
    at AsyncSeriesHook.lazyCompileHook [as _callAsync] (/home/xxx/node_modules/webpack/node_modules/tapable/lib/Hook.js:35:21)
    at asyncLib.forEach.err (/home/xxx/node_modules/webpack/lib/Compiler.js:302:27)
    at done (/home/xxx/node_modules/neo-async/async.js:2809:11)
    at /home/xxx/node_modules/neo-async/async.js:2760:7
    at MemoryFileSystem.writeFile (/home/xxx/node_modules/memory-fs/lib/MemoryFileSystem.js:328:9)
    at writeOut (/home/xxx/node_modules/webpack/lib/Compiler.js:286:29)
    at asyncLib.forEach (/home/xxx/node_modules/webpack/lib/Compiler.js:296:7)
    at baseEach (/home/xxx/node_modules/neo-async/async.js:2371:9)
    at Object.each (/home/xxx/node_modules/neo-async/async.js:2798:9)
  code: 'EINVAL',
  errno: 18,
  message: 'invalid argument',
  path: '.' }

So do you have any idea how to fix this?

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 24 (24 by maintainers)

Most upvoted comments

@ztoben It’s working with 3.8.4-alpha.1

@ztoben, I know where the problem is coming from: https://github.com/ztoben/assets-webpack-plugin/blob/869563b6fba6e4e0ec4a1b824e8b7ce12838d62e/index.js#L14 Path is hardcoded there, as ".", but it should come from compiler.options.output.path instead (at the time where the plugin is applied)

So that line above (path: '.') should not exist, and line https://github.com/ztoben/assets-webpack-plugin/blob/869563b6fba6e4e0ec4a1b824e8b7ce12838d62e/index.js#L29 could be something like:

self.options.path = self.options.path || compiler.options.output.path;

The thing is path must be absolute, and should default to the path from the compiler options output path.

@ztoben, What I’d do is reapply the pull request and normalize the path, making it absolute, by using resolve():

var path = require("path");

...

    var absolutePath = path.resolve(options.path);
    fs.mkdirp(absolutePath, function (err) {
      if (err) {
        return next(error('Could not create output folder ' + absolutePath, err))
      }

      var outputPath = fs.join(absolutePath, options.filename)

      ...
    }

in here: https://github.com/kossnocorp/assets-webpack-plugin/blob/804aa0ed2c6d797ff61a29d84d6ceda7bbb5586d/lib/output/createOutputWriter.js#L17

Maybe @Trainmaster could help verifying that fixes it.

Edit: Apparently, paths should be absolute here, but they aren’t, in this edit, I propose using resolve() to make the path absolute before passing to mkdirp().

@ztoben Fixed with 3.8.0, thanks!