我想用gulp完成一些简单的事情。我想编写一个通用方法将文件从特定的源目录移动到输出目录。
假装我们有类似的东西
var args = require('yargs');
function transform-move-jsx-Development()
{
gulp.src(config.sourceJSX)
.pipe(react, browserify, etc....)
.pipe(gulp.dest(config.output_development));
};
function transform-move-jsx-Production()
{
gulp.src(config.sourceJSX)
.pipe(react, browserify, etc....)
.pipe(gulp.dest(config.output_production));
};
gulp.task('transform-move-jsx-Development', transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);
gulp.task('prod', [transform-move-jsx-Production]);
gulp.task('dev', ['transform-move-jsx-Development']);
这两个任务:transform-move-jsx-Production和transform-move-jsx-Development除了输出目录外是相同的。我想让它更干(不要重复自己)。我应该能够制作一个可以使用yarg参数的方法吗?在下一个例子中,我假装我可以将路径作为arg传递
所以我尝试使用yargs
这样的东西var args = require('yargs');
function transform-move-jsx()
{
return gulp.src(config.sourceJSX)
.pipe(gulp.dest(args.outputDirectory));
};
gulp.task('dev', ['transform-move-jsx']);
但是现在要求我在命令行
中为gulp调用添加参数gulp dev --"path to output, etc."
当我们从dev gulp任务中调用越来越多的gulp任务时,这显然不太可维护。反之亦然,因为我们不需要知道一个实现细节,比如运行gulp dev
我可以做这样的事情:
function transform-move-jsx(destination)
{
return gulp.src(config.sourceJSX)
.pipe(gulp.dest(destination));
};
function transform-move-jsx-Development()
{
transform-move-jsx("./output/development/");
};
function transform-move-jsx-Production()
{
transform-move-jsx("./output/production/");
};
gulp.task('transform-move-jsx-Development',transform-move-jsx-Development);
gulp.task('transform-move-jsx-Production', transform-move-jsx-Production);
gulp.task('prod', transform-move-jsx-Production);
gulp.task('dev', transform-move-jsx-Development);
这似乎更好,因为它更灵活,但是现在我的gulp文件中充斥着几个不必要的函数。
有更好的方法吗?
答案 0 :(得分:27)
第二次尝试时你走在正确的轨道上,只需要使用一点DRY和closures
function createTransformTaskClosure (destination) {
return function () {
return gulp.src(config.sourceJSX)
.pipe(gulp.dest(destination));
};
}
gulp.task('dev', createTransformTaskClosure(config.output_development));
gulp.task('prod', createTransformTaskClosure(config.output_production));
答案 1 :(得分:1)
我使用单一功能做了类似的事情:
function getDest(folder){
var folder = folder || '';
var newDest;
if (args.build){
newDest = config.build.home + folder;
}
if (args.temp){
newDest = config.temp.home + folder;
}
return newDest;
}
然后,当我打电话给gulp.dest():
.pipe(gulp.dest(getDest())) // defaults to ./ directory
或者,如果我想要一个子文件夹:
.pipe(gulp.dest(getDest(config.css)))
我的配置文件只有路径,即:
config = {
css: '/css/',
home: './',
js: '/js/'
}
希望有所帮助。
答案 2 :(得分:0)
首先,记录相关的github问题gulp#1225。
Gulp无法处理任务中的参数。为了处理开发/生产构建,我们可以使用yargs和gulp-if:
var gulp = require('gulp');
var argv = require('yargs').argv;
var gulpif = require('gulp-if');
var production = argv.production;
然后,例如,在CSS任务中:
return gulp.src(paths.css)
.pipe(gulpif(!production, sourcemaps.init()))
.on('error', handleError('CSS'))
.pipe(concat('style.min.css'))
.pipe(gulpif(production, autoprefixer(config.autoprefixer_versions)))
.pipe(gulpif(production, minifyCSS()))
.pipe(sourcemaps.write())
.pipe(gulp.dest(paths.build + 'css/'));
如您所见,使用gulp-if正确处理管道。
但是上面仍然需要使用gulp mytask --production
运行gulp,并且如果确实需要在一个构建中多次运行相同的任务,则不适合。它不合适,因为它根本不是DRY。
例如,如果您需要为不同的站点部分生成许多CSS构建,则必须重复上述任务n次。但由于gulp无法处理参数,我们需要做类似的事情:
var taskMethods = {
css: function (paths) {
return gulp.src(paths.css)
.pipe(gulpif(!production, sourcemaps.init()))
.on('error', handleError('CSS'))
.pipe(concat('style.min.css'))
.pipe(gulpif(production, autoprefixer(config.autoprefixer_versions)))
.pipe(gulpif(production, minifyCSS()))
.pipe(sourcemaps.write())
.pipe(gulp.dest(paths.build + 'css/'));
}
};
var pathsIndex = {
css: [...],
build: '...'
};
var tasksIndex = {
css: function() { return taskMethods(pathsIndex); }
}
var pathsAdmin = {...};
var tasksAdmin = {...};
gulp.task('cssIndex', tasksIndex.css);
gulp.task('cssAdmin', tasksAdmin.css);
基本上我们将任务方法与gulp任务分开,并且必须为使用特定路径配置的新函数指定任务方法的“连接”成本。但这样做的好处是,无论何时需要对任务方法进行更改,它都在一个地方。您还可以轻松查看网站的哪个部分使用哪种方法。
这也是我在gulpfile project中处理此问题的方法。
答案 3 :(得分:0)
如下所示:
var args = require('yargs');
function transform-move-jsx(destination) {
return function(){
return gulp.src(config.sourceJSX)
.pipe(react, browserify, etc....)
.pipe(gulp.dest(destination));
}
};
gulp.task('transform-move-jsx-Development', transform-move-jsx(config.output_development));
gulp.task('transform-move-jsx-Production', transform-move-jsx(config.output_production));
gulp.task('prod', [transform-move-jsx-Production]);
gulp.task('dev', ['transform-move-jsx-Development']);
答案 4 :(得分:0)
派对有点晚了。我有类似的问题,找不到简单的解决方案,所以我想出了这种方法来使用npm和gulp的组合。
说你的gulpfile是:
var args = require('yargs');
function transform-move-jsx()
{
return gulp.src(config.sourceJSX)
.pipe(gulp.dest(args.outputDirectory));
};
你的npm文件:
{
...
"scripts": {
"dev" : "gulp transform-moove-jsx --./output/development/ && gulp one && gulp two",
"prod" : "gulp transform-moove-jsx --./output/production/ && gulp one && gulp two",
}
}
这种方法要求你已经在你的设置中使用npm,是系统相关的,并且运行效率较低,可能产生副作用,因为每个npm任务都会多次运行gulp文件。但我认为它更清洁,更符合逻辑,并消除了一大堆限制。
答案 5 :(得分:0)
有帮助吗?
const { src, dest, series } = require('gulp');
function moveJSX(dest = "./output/development/", label = "dev") {
const source = config.sourceJSX;
function task() { return src(source).pipe(dest(dest)); };
task.displayName = `moveJSX:${label}`;
return task;
}
// usage
series(moveJSX(), moveJSX("./output/production/", "prod"));
请随时删除标签内容。
答案 6 :(得分:-1)
不确定这是否有用,但只是我的几个便士的想法: -
在gulp文件中包含以下内容。
var args = require('yargs'),
config = require('./config.js'),
run = require('gulp-sequence');
gulp.task('transform-move-jsx-all', function() {
return gulp.src(config.sourceJSX)
.pipe(react, browserify, etc....)
.pipe(gulp.dest(config.current.output));
};
gulp.task('prod', function(done) {
config.current = config.prod;
run( 'transform-move-jsx' /* and any additional sequential tasks here*/)(done);
});
gulp.task('dev', function(done) {
config.current = config.dev;
run( 'transform-move-jsx' /* and any additional sequential tasks here*/)(done);
});
这样就可以让您完成简单的任务,例如gulp dev
或gulp prod
。
它希望config.js
文件类似于下面的文件:
var config = {
current : {
// Will set when running each task
},
/* Keep dev and prod adhering to the same structure/model so that they are interchangable */
dev : {
output : 'dev_output',
},
prod : {
output : 'prod_output'
},
sourceJSX : [ 'file1.jsx' ],
etc...
}
使用yargs可能有更简洁的方法,但如果你只想要一个干净的gulp + task
,那么这就是我要采取的方向。