My question begins with another one, asked here: Gulp: How to set dest folder relative to processed file (when using wildcards)?
I have a similar situation, where I need to make compressed versions on a per-module basis. That is, I have
ui/test/one/script1.js
ui/test/two/script2.js
and I need to have gulp copy the files into relative directories so I end up with
ui/test/one/compressed/script1.js
ui/test/two/compressed/script2.js
I have the following gulp task
gulp.task('test', function() {
return gulp.src('ui/test/**/*.js')
.pipe(gulp.dest(function(file) {
return path.join(path.dirname(file.path), 'compressed');
}));
});
However, when I run it, I end up with
ui/test/one/compressed/one/script1.js
ui/test/two/compressed/two/script2.js
I see in the docs where it says
cwd - Specify the working directory the folder is relative to. base - Specify the folder relative to the cwd. Default is where the glob begins. This is used to determine the file names when saving in .dest()
I have several questions, specifically about .src()
, .dest()
and the path and file objects. (That is, although I'm sure there are other ways to achieve my end goal, this question is specifically about the behavior of the sample gulp code above and the functions mentioned so I can understand their behavior and API better.)
Questions
some/folder/a/b/c/foo.js
I'm not sure if the base is some/folder/
, some/folder/a/
, or some/folder/a/b/c/
?<where the glob begins> + '..'
?C:\blah\ui\test\one\compressed
. It follows then that whatever's decided the actual name of the file has one\script1.js
in mind. How do I change its mind so that it's only thinking of script1.js
?Note: I tried doing the following (using gulp-debug)
gulp.task('test', function() {
return gulp.src('ui/test/**/*.js', {cwd: './'})
.pipe(debug({minimal: false}))
.pipe(rename(function(path) {
path.basename = path.basename.substring(path.basename.lastIndexOf('\\') + 1);
}))
.pipe(debug({minimal: false}))
.pipe(gulp.dest(function(file) {
return path.join(path.dirname(file.path), 'compressed');
}));
});
The console has the following output for this version of the task:
cwd: ./
base: C:\blah\ui\test
path: C:\blah\ui\test\one\script1.js
cwd: ./
base: C:\blah\ui\test
path: C:\blah\ui\test\one\script1.js
cwd: ./
base: C:\blah\ui\test
path: C:\blah\ui\test\two\script2.js
cwd: ./
base: C:\blah\ui\test
path: C:\blah\ui\test\two\script2.js
So it appears that the rename has no effect on the path. I also tried modifying path.dirname in the rename pipe, but couldn't find anything that would have the desired effect of simply removing the spurious directory name from the final output path.
My last question, then, is what exactly do path.basename and path.dirname contain for the path object passed to the rename function?
edit: I found this on how to debug gulp tasks. Doing so with a debugger;
statement placed in the rename function allowed me to inspect the path object, which looks like this:
{
basename: "script1",
dirname: "one",
extname: ".js"
}
Setting path.dirname to ''
in the rename results in
ui/test/compressed/script1.js
ui/test/compressed/script2.js
so it may be that rename() itself is not useful for what I need. It's looking more like the base option to .src() may be where the key lies, but the docs are rather terse.
Question 1:
gulp.src('ui/test/**/*.js')
This line is setting '/ui/test/' as your root directory ('working file directory'), as it is the base of your glob pattern. That's why the 'relative paths' fed to dest were 'one/script1.js' and 'two/script2.js'.
Question 2:
By glob, the docs are referring to your '**/*.js' pattern. So the base of your glob is the same thing that it's using as your root directory, '/ui/test/', which in this case means the same things as "folder relative to the cwd".
Question 3:
The 'base' property for each path is being set similar to the glob2base module for each file coming from the gulp.src stream.
glob2base(new glob.Glob('/ui/test/**/*.js')) + '..';
is the same as
file.base + '..';
if that makes sense to you.
Question 4:
I assume you're using gulp-rename in your second section of code. So this should solve your problem.
gulp.src('ui/test/**/*.js')
.pipe(rename(function(path){
path.basename = 'compressed/' + path.basename;
})
.pipe(gulp.dest(function(file) {
return file.base;
}));
The other options that can be passed to gulp.src can be found here, but I don't think any of them directly solve what you're trying to do. gulp.src doesn't seem to expect you to hack in a new directory in the middle of each path, so renaming is the simplest solution.
I don't blame you for having issues figuring out the docs. I had to jump between three or four different github pages to piece together everything going on. Hope you learned as much as I did from this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With