I'm working on a custom generator that I originally wrote with grunt-init. One difference I'm noticing is grunt-init automatically processes all the files in root as templates but with yeoman generator you have to do this using .template(). I'm familiar with how to process any individual file with .template() but is it possible to process an entire directory?
3 Answers
This issue is an annoying one. I came across this when I used yeoman for the first time. I think the below code snippet can help you.
this.directory('scripts', 'scripts');// script is folder name
-
6This will bulkCopy all files from one directory to another with out templateing files. – floatdrop Dec 26 '13 at 15:26
-
1At least in the recent versions of Yeoman this works by applying templating and conflict checking (there is another function called bulkDirectory to avoid both). Sadly I couldn't find a way to avoid template processing but keep the conflict checking. Note that if the source is the same as dest you can skip it: `this.directory('scripts')`.. learned from the source: http://yeoman.github.io/generator/actions.js.html – Diego May 10 '14 at 23:34
-
@Diego The link you provided is dead. Can you provide a new one? – SKuijers Sep 23 '15 at 12:35
-
2@SKuijers np seems that Yeoman updated the docs site recently, new link: http://yeoman.github.io/generator/lib_actions_actions.js.html – Diego Sep 23 '15 at 13:50
Looking at the Yeoman generator code, there doesn't seem to be a built in way to do this. The way I solved this was to copy some of the code from the built in generator code and modify it for my needs. I determine if a file is a template based on the _
prefix convention since I want to rename the files to exclude that prefix, but you could just treat every file as a template and it would work fine. This will copy all of the files in the directory, so what I also did is to exclude the .DS_STORE
files that you find by default on OSX, but since that is a specific case I didn't include that here.
require('path');
MyGenerator.prototype._processDirectory = function(source, destination) {
var root = this.isPathAbsolute(source) ? source : path.join(this.sourceRoot(), source);
var files = this.expandFiles('**', { dot: true, cwd: root });
for (var i = 0; i < files.length; i++) {
var f = files[i];
var src = path.join(root, f);
if(path.basename(f).indexOf('_') == 0){
var dest = path.join(destination, path.dirname(f), path.basename(f).replace(/^_/, ''));
this.template(src, dest);
}
else{
var dest = path.join(destination, f);
this.copy(src, dest);
}
}
};

- 7,676
- 1
- 24
- 33
Yeoman uses mem-fs-editor, which has support for glob patterns. However the documentation is not very clear, and you may miss that point. Here is the documentation of copyTpl, that says it accepts the same options as copy. So since copy has suppport for glob patterns, copyTpl too.
At any point on your yeoman generator you can do:
const from = 'myFolder/**.js'
const to = 'project/'
this
.fs
.copyTpl(
this.templatePath(from),
this.destinationPath(to),
this.props, {interpolate: /<%=([\s\S]+?)%>/g}
);
},
Not that, if you are using a glob pattern the destination path should be a folder.

- 5,996
- 4
- 32
- 66
-
I've tried exactly this with the most recent version of Yeoman, and it copies nothing, whether or not the "project" folder exists. I've even expanded the globbing pattern to './**/*' in attempt to get any files at all to copy over, and nothing comes through, regardless of folder depth, filename, or extension. Globbing just seems to do nothing at all. – Artif3x May 23 '18 at 14:56
-
This works for me in current yeoman version, thanks. People testing need to create the myFolder and put files inside to work – Alberto Souza Jan 21 '20 at 18:35