How do I interact with this <File> object in a node.js stream?

I'm using gulp to build a stream of glob-matched files and move them all, in their nested structure, to a new location. To do this, I first wanted to build a simple 'through' stream to see what I get passed if I pipe to it from gulp.src().

Here is my test gulpfile.js:

var through = require("through");
var fs = require("fs");

function write(file) {
  console.log(file);
  console.log(file.toString());
}

gulp.task("move", function () {

  return gulp.src("./**")
    .pipe(through(write));

});

If I run the gulp 'move' task on the command line, I get output like the following:

<File "some/path">
[object Object]
<File "some/path/file.js" <Buffer 2f 2a 0a 0a 4f 72 67 69 6e 61 6c 20 53 74 79 6c 65 20 66 72 6f 6d 20 65 74 68 61 6e 73 63 68 6f 6f 6e 6f 76 65 72 2e 63 6f 6d 2f 73 6f 6c 61 72 69 7a 65 ...>>
[object Object]

What are those objects? How can I interact with them?

Answers


Those are vinyl objects. They are the core data type passed through gulp streams. The contain information about the file (such as path info and contents as a buffer or stream). You can see the data better using gulp-debug.

If you want to move a bunch of files, while preserving their relative path, you can do one of the following, no need to dig into the code yourself:

gulp.src('/a/single/src/path/**/*.foo').pipe(gulp.dest('/a/single/dest/path'));

Or, if you have a bunch of different globs:

gulp.src(['/a/src/path/foo/**/*.foo', '/a/src/path/bar/**/*.bar'], {base: '/a/src/path/'})
    .pipe(gulp.dest('/a/dest/path/'));

Mostly you'll be using gulp plugins to manipulate the files, then passing the result to gulp.dest(), rather than manipulating them yourself.

If you need to manipulate the files, there's a few plugins that can help:

  • gulp-tap allows you to peak into the stream, and optionally modify the file or buffer.
  • vinyl-map lets you easily modify the contents of files
  • gulp-filter can help you filter the stream if globbing doesn't work.

You can view the file properties using this js:

var propValue;
for(var propName in file) {
    propValue = file[propName];
    console.log('name:' + propName, ', value:<<<',propValue,'>>>');
}

Sample Output
    name:history ,     value:"C:\Temp\test.txt"
    name:cwd ,         value:"C:\Temp"
    name:base ,        value:"C:\Temp"
    name:_contents ,   value: full file contents
    name:isBuffer ,    value:"function () {
    name:isStream ,    value:"function () {
    name:isNull ,      value:"function () {
    name:isDirectory , value:"function () {
    name:clone ,       value:"function (opt) {
    name:pipe ,        value:"function (stream, opt) {
    name:inspect ,     value:"function () {
    name:stat , value:<<< { dev: 0,
      mode: 33206,
      nlink: 1,
      uid: 0,
      gid: 0,
      rdev: 0,
      ino: 0,
      size: 874,
      atime: Sat Sep 19 2015 14:34:51 GMT+1000 (AUS Eastern Standard Time),
      mtime: Sat Sep 19 2015 14:34:51 GMT+1000 (AUS Eastern Standard Time),
      ctime: Sat Sep 12 2015 14:59:40 GMT+1000 (AUS Eastern Standard Time) } >>>

Usage:
console.log('file name:', file.relative);
console.log('file current working directory:', file.cwd);
console.log('file isDirectory:', file.isDirectory());

For those who also stumbled upon this and don't want to use gulp, here is how I did it:

Assuming files is an array of vinyl objects -

        const outputPath = ... // some directory path

        files.forEach(file => {
            const filePath = path.join(outputPath, file.relative);
            // if its a directory then create the directory if not already present
            if (file.isDirectory()) {
              if (!fs.existsSync(filePath)) {
                fs.mkdirSync(filePath, { recursive: true });
              }
            } else {
              // if its a file then save the contents of the file
              fs.writeFileSync(filePath, file.contents);
            }
          });

Need Your Help

How to change Hash values?

ruby syntax hash

I'd like to replace each value in a hash with value.some_method.

Code first migrations - what connection string will it use?

entity-framework connection-string code-first ef-migrations ef-model-first

Code first migrations have been working very well for me. I have a services project and a wpf project. The model is in the services project which is referenced by the wpf project. Update-databas...