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']);
2つのタスク、transform-move-jsx-Productionとtransform-move-jsx-Developmentは、出力ディレクトリを除いて同じです。もっと増やしたいDRY(Do n't Repeat Yourself)。私は、yargパラメータなどを使用できる単一のメソッドを作成できるはずですか?この次の例では、パスを引数として渡すことができます
だから私は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);
これはより柔軟であるという点で優れているようですが、私のgulpfileにはいくつかの不要な関数が散らばっています。
より良い方法はありますか?
あなたは2回目の試行で正しい軌道に乗っていましたが、少し [〜#〜] 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));
私は単一の関数を使用して同様のことをしました:
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/'
}
お役に立てば幸いです。
次のようなものはどうですか:
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']);
パーティーに少し遅れました。同様の問題があり、簡単な解決策が見つからなかったので、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ファイルを複数回実行するため、副作用があり、効率が低下します。しかし、私はそれをよりクリーンで、より論理的であり、gulpの多くの制限を取り除くと考えています。
まず、記録として、関連するgithubの問題 gulp#1225 です。
Gulpはタスクのパラメーターを処理できません。 dev/productionビルドを処理するために、 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を実行する必要があり、実際に同じタスクを1つのビルドで複数回実行する必要がある場合は、実際には適していません。 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タスクから分離します。特定のパス構成を使用する新しい関数へのタスクメソッドの「ワイヤーアップ」を指定する必要があります。しかし、これには、タスクメソッドに変更を加える必要があるときはいつでも、それが1か所にあるという利点があります。また、サイトのどの部分がどの方法を使用しているかを簡単に確認できます。
gulpfileプロジェクト でこの問題に対処する方法もこれです。