我是gulp的新手,但我想知道是否可以在gulp任务中遍历目录。
这就是我的意思,我知道很多教程/演示显示使用“** / * .js”之类的东西处理一堆JavaScript文件,然后将它们编译成单个JavaScript文件。但是我想迭代一组目录,并将每个目录编译成它自己的JS文件。
例如,我有一个文件结构,如:
/js/feature1/something.js
/js/feature1/else.js
/js/feature1/foo/bar.js
/js/feature1/foo/bar2.js
/js/feature2/another-thing.js
/js/feature2/yet-again.js
...我想要两个文件:/js/feature1/feature1.min.js
和/js/feature2/feature2.min.js
,其中第一个包含前4个文件,第二个包含最后2个文件。
这可能,或者我是否必须手动将这些目录添加到清单?实际迭代/js/
中的所有目录真的很不错。
感谢您提供任何帮助。
-Nate
编辑:应该注意的是,我不仅有2个目录,但我有很多(可能是10-20个),所以我真的不想为每个目录编写任务。我想以相同的方式处理每个目录:获取其中的所有JS(以及任何子目录)并将其编译为基于特征的缩小JS文件。
答案 0 :(得分:44)
这是官方配方:Generating a file per folder
var fs = require('fs');
var path = require('path');
var merge = require('merge-stream');
var gulp = require('gulp');
var concat = require('gulp-concat');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var scriptsPath = 'src/scripts';
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function(file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
gulp.task('scripts', function() {
var folders = getFolders(scriptsPath);
var tasks = folders.map(function(folder) {
return gulp.src(path.join(scriptsPath, folder, '/**/*.js'))
// concat into foldername.js
.pipe(concat(folder + '.js'))
// write to output
.pipe(gulp.dest(scriptsPath))
// minify
.pipe(uglify())
// rename to folder.min.js
.pipe(rename(folder + '.min.js'))
// write to output again
.pipe(gulp.dest(scriptsPath));
});
// process all remaining files in scriptsPath root into main.js and main.min.js files
var root = gulp.src(path.join(scriptsPath, '/*.js'))
.pipe(concat('main.js'))
.pipe(gulp.dest(scriptsPath))
.pipe(uglify())
.pipe(rename('main.min.js'))
.pipe(gulp.dest(scriptsPath));
return merge(tasks, root);
});
答案 1 :(得分:16)
您可以使用glob
获取目录列表并对其进行迭代,使用gulp.src
为每个功能创建单独的管道。然后,您可以返回一个在所有流都有end
ed。
var fs = require('fs');
var Q = require('q');
var gulp = require('gulp');
var glob = require('glob');
gulp.task('minify-features', function() {
var promises = [];
glob.sync('/js/features/*').forEach(function(filePath) {
if (fs.statSync(filePath).isDirectory()) {
var defer = Q.defer();
var pipeline = gulp.src(filePath + '/**/*.js')
.pipe(uglify())
.pipe(concat(path.basename(filePath) + '.min.js'))
.pipe(gulp.dest(filePath));
pipeline.on('end', function() {
defer.resolve();
});
promises.push(defer.promise);
}
});
return Q.all(promises);
});
答案 2 :(得分:4)
我正在努力了解流如何在节点中工作。 我为您做了一个简单的示例,介绍了如何使流过滤文件夹并为它们启动新的给定流。
'use strict';
var gulp = require('gulp'),
es = require('event-stream'),
log = require('consologger');
// make a simple 'stream' that prints the path of whatever file it gets into
var printFileNames = function(){
return es.map(function(data, cb){
log.data(data.path);
cb(null, data);
});
};
// make a stream that identifies if the given 'file' is a directory, and if so
// it pipelines it with the stream given
var forEachFolder = function(stream){
return es.map(function(data, cb){
if(data.isDirectory()){
var pathToPass = data.path+'/*.*'; // change it to *.js if you want only js files for example
log.info('Piping files found in '+pathToPass);
if(stream !== undefined){
gulp.src([pathToPass])
.pipe(stream());
}
}
cb(null, data);
});
};
// let's make a dummy task to test our streams
gulp.task('dummy', function(){
// load some folder with some subfolders inside
gulp.src('js/*')
.pipe(forEachFolder(printFileNames));
// we should see all the file paths printed in the terminal
});
因此,在您的情况下,您可以使用文件夹中的文件创建一个流(如缩小它们并连接它们),然后将此流的实例传递给forEachFolder
流我制作。就像我使用printFileNames
自定义流一样。
尝试一下,让我知道它是否适合你。
答案 3 :(得分:0)
首先,安装gulp-concat& gulp-uglify
$ npm install gulp-concat
$ npm install gulp-uglify
接下来,执行以下操作:
//task for building feature1
gulp.task('minify-feature1', function() {
return gulp.src('/js/feature1/*')
.pipe(uglify()) //minify feature1 stuff
.pipe(concat('feature1.min.js')) //concat into single file
.pipe(gulp.dest('/js/feature1')); //output to dir
});
//task for building feature2
gulp.task('minify-feature2', function() { //do the same for feature2
return gulp.src('/js/feature2/*')
.pipe(uglify())
.pipe(concat('feature2.min.js'))
.pipe(gulp.dest('/js/feature2'));
});
//generic task for minifying features
gulp.task('minify-features', ['minify-feature1', 'minify-feature2']);
现在,您需要做的就是从CLI中缩小所有内容:
$ gulp minify-features
答案 4 :(得分:0)
我在使用gulp配方时遇到了麻烦,也许是因为我使用的是gulp 4和/或因为我还是不想合并所有文件夹的输出。 我调整了配方以在每个文件夹中生成(但不运行)匿名函数,并返回函数数组,以使它们能够由gulp.parallel处理-以某种方式生成的函数数是可变的。这种方法的关键是:
每个生成的函数都必须是一个函数或组合(而不是流)。就我而言,每个生成的函数都是一个序列组成,因为在构建每个模块文件夹时我要做很多事情。
函数数组需要使用javascript apply()传递到我的构建任务中,因为在我的案例中,数组的每个成员都需要转换为gulp.parallel的参数。 我的函数摘录生成了函数数组:
function getModuleFunctions() {
//Get list of folders as per recipe above - in my case an array named modules
//For each module return a function or composition (gulp.series in this case).
return modules.map(function (m) {
var moduleDest = env.folder + 'modules/' + m;
return gulp.series(
//Illustrative functions... all must return a stream or call callback but you can have as many functions or compositions (gulp.series or gulp.parallel) as desired
function () {
return gulp.src('modules/' + m + '/img/*', { buffer: false })
.pipe(gulp.dest(moduleDest + '/img'));
},
function (done) {
console.log('In my function');
done();
}
);
});
}
//Illustrative build task, running two named tasks then processing all modules generated above in parallel as dynamic arguments to gulp.parallel, the gulp 4 way
gulp.task('build', gulp.series('clean', 'test', gulp.parallel.apply(gulp.parallel, getModuleFunctions())));
`