how base option affects gulp.src & gulp.dest

2019-01-13 21:45发布

问题:

I encountered an issue trying to copy a set of files and when calling .dest('some folder') the entire folder structure was lost.

I searched and found an answer suggesting that I should provide {base:'.'} as an option on my call to gulp.src(...) to resolve this issue.

The documentation for gulp.src options only says that its options are:

Options to pass to node-glob through glob-stream.

Looking into node-glob documentation for its options base is not listed there at all.
And the glob-stream options documentation only states that

"the Default is everything before a glob starts (see glob-parent)"

So no much help here either.

So, what effect does the base option passed to gulp.src have on the viny6l files in the created stream and how does it effect the gulp.dest command ?

回答1:

(You're not looking at the official gulp documentation. http://github.com/arvindr21/gulp is just some guy's fork of the gulpjs github repo. The official repo is http://github.com/gulpjs/gulp/ where the base option is indeed documented.)

To answer your question:

If you don't specify the base option yourself, then everything before the first glob in your gulp.src() paths is automatically used as the base option and ommitted when writing to the destination folder.

Say you have the following files:

some/path/example/app/js/app.js
some/path/example/vendor/js/vendor.js
some/path/example/vendor/lib/js/lib.js

And this is your Gulpfile.js:

gulp.src('some/path/**/js/*.js')
  .pipe(gulp.dest('output'));

In this case everything before the ** is automatically used as your base option. So the above is essentially equivalent to this:

gulp.src('some/path/**/js/*.js', {base:'some/path/'})
  .pipe(gulp.dest('output'));

What this means is that some/path/ is stripped from the path of every file that matches the pattern in gulp.src(). The resulting structure in the output folder looks like this:

output/example/app/js/app.js
output/example/vendor/js/vendor.js
output/example/vendor/lib/js/lib.js

So a certain part of the directory structure of your source files is indeed lost. How much of your directory structure you lose depends on where the first glob in your gulp.src() pattern is.

If you want to avoid this you have to explicitly specify the base option:

gulp.src('some/path/**/js/*.js', {base:'.'})
  .pipe(gulp.dest('output'));

Now some/path/ will not be stripped from your file paths, resulting in the following folder structure in output:

output/some/path/example/app/js/app.js
output/some/path/example/vendor/js/vendor.js
output/some/path/example/vendor/lib/js/lib.js

EDIT: If you pass an array of patterns to gulp.src() there's no way to specify a different base option for each of the array elements. This for example won't work:

gulp.src(
  ['source1/examples/**/*.html',
   'source2/examples/**/*.html'],
  { base: ['source1/',    // Doesn't work. 
           'source2/']}   // Needs to be a string.
).pipe(gulp.dest('dist'));

Instead you have to follow the "Using multiple sources in one task" recipe. This lets you merge two streams each of which can receive its own base option:

var merge = require('merge-stream');

gulp.task('default', function() {
  merge(gulp.src('source1/examples/**/*.html', {base: 'source1/'}),
        gulp.src('source2/examples/**/*.html', {base: 'source2/'}))
   .pipe(gulp.dest('dist'));
});


标签: gulp