New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecating gulp.run no longer allows defining logic before running tasks. #193

Closed
timrwood opened this Issue Jan 25, 2014 · 28 comments

Comments

Projects
None yet
@timrwood

timrwood commented Jan 25, 2014

Given a gulp file similar to the one below, before version 3.5 I was able to run some logic before running other tasks.

var shouldMinify = false;

gulp.task('js', function () {
    return gulp.src('./js/*.js')
        .pipe(concat('app.js'))
        .pipe(gulpif(shouldMinify, uglify()))
        .pipe(gulp.dest('js'));
});

gulp.task('develop', function () {
    shouldMinify = false;
    gulp.run('js');
});

gulp.task('build', function () {
    shouldMinify = true;
    gulp.run('js');
});

As gulp.run is now deprecated, the only way to have a task run other tasks is by specifying them as dependencies. This feels extremely limiting, as the only way to set some logic before running a task is by using command line flags like in this example.

I may have missed it in the issues, but are there plans for programmatically starting tasks other than adding them as dependencies of other tasks?

@phated

This comment has been minimized.

Show comment
Hide comment
@phated

phated Jan 25, 2014

Member

gulp.run will continue to work until 4.0, at which time it will be replaced with orchestrator.start or a similar API if orchestrator is replaced.

The reason for the deprecation was incorrect use of gulp.run, resulting in an insane amount of issues regarding nested gulp.run calls in some weird attempt to run synchronous tasks.

Not to mention, you should control this type of logic with environment variables or command line flags.

var shouldMinify = false;

function js(shouldMinify) {
    return gulp.src('./js/*.js')
        .pipe(concat('app.js'))
        .pipe(gulpif(shouldMinify, uglify()))
        .pipe(gulp.dest('js'));
});

gulp.task('develop', function () {
    shouldMinify = false;
    return js(shouldMinify);
});

gulp.task('build', function () {
    shouldMinify = true;
    return js(shouldMinify);
});

The above should be the way you actually write your example, which just goes to show that gulp.run severely restricts cognisance of what you are actually writing.

Member

phated commented Jan 25, 2014

gulp.run will continue to work until 4.0, at which time it will be replaced with orchestrator.start or a similar API if orchestrator is replaced.

The reason for the deprecation was incorrect use of gulp.run, resulting in an insane amount of issues regarding nested gulp.run calls in some weird attempt to run synchronous tasks.

Not to mention, you should control this type of logic with environment variables or command line flags.

var shouldMinify = false;

function js(shouldMinify) {
    return gulp.src('./js/*.js')
        .pipe(concat('app.js'))
        .pipe(gulpif(shouldMinify, uglify()))
        .pipe(gulp.dest('js'));
});

gulp.task('develop', function () {
    shouldMinify = false;
    return js(shouldMinify);
});

gulp.task('build', function () {
    shouldMinify = true;
    return js(shouldMinify);
});

The above should be the way you actually write your example, which just goes to show that gulp.run severely restricts cognisance of what you are actually writing.

@phated phated closed this Jan 25, 2014

@contra

This comment has been minimized.

Show comment
Hide comment
@contra

contra Jan 25, 2014

Member

gulp.run is a crutch people were abusing - use plain old JS patterns to solve problems now.

Member

contra commented Jan 25, 2014

gulp.run is a crutch people were abusing - use plain old JS patterns to solve problems now.

@timrwood

This comment has been minimized.

Show comment
Hide comment
@timrwood

timrwood Jan 25, 2014

@phated, your example works well for one stream, but starts to get complicated when you need to run more than one task.

gulp.task('develop', function () {
    var promise = Q.defer();
    Q.all(css(false), js(false), img(false), html(false)).then(promise.resolve);
    return promise.promise;
});

gulp.task('build', function () {
    var promise = Q.defer();
    Q.all(css(true), js(true), img(true), html(true)).then(promise.resolve);
    return promise.promise;
});

timrwood commented Jan 25, 2014

@phated, your example works well for one stream, but starts to get complicated when you need to run more than one task.

gulp.task('develop', function () {
    var promise = Q.defer();
    Q.all(css(false), js(false), img(false), html(false)).then(promise.resolve);
    return promise.promise;
});

gulp.task('build', function () {
    var promise = Q.defer();
    Q.all(css(true), js(true), img(true), html(true)).then(promise.resolve);
    return promise.promise;
});
@contra

This comment has been minimized.

Show comment
Hide comment
@contra

contra Jan 25, 2014

Member

@timrwood use gulp-if in your tasks to minify based on vars then just use normal task dependencies to run multiple tasks

Member

contra commented Jan 25, 2014

@timrwood use gulp-if in your tasks to minify based on vars then just use normal task dependencies to run multiple tasks

@phated

This comment has been minimized.

Show comment
Hide comment
@phated

phated Jan 25, 2014

Member

@timrwood if your functions are promise returning, there is no reason to use a deferred. You are just writing complicated code for no reason.

function all(minify){
    return Q.all(css(minify), js(minify), img(minify), html(minify));
}

gulp.task('develop', function () {
     return all(false); 
});

gulp.task('build', function () {
    return all(true);
});
Member

phated commented Jan 25, 2014

@timrwood if your functions are promise returning, there is no reason to use a deferred. You are just writing complicated code for no reason.

function all(minify){
    return Q.all(css(minify), js(minify), img(minify), html(minify));
}

gulp.task('develop', function () {
     return all(false); 
});

gulp.task('build', function () {
    return all(true);
});
@timrwood

This comment has been minimized.

Show comment
Hide comment
@timrwood

timrwood Jan 25, 2014

@contra, the point I'm trying to make is that for a task running module, it seems like a step backwards to no longer be able to programmatically run tasks.

timrwood commented Jan 25, 2014

@contra, the point I'm trying to make is that for a task running module, it seems like a step backwards to no longer be able to programmatically run tasks.

@phated

This comment has been minimized.

Show comment
Hide comment
@phated

phated Jan 25, 2014

Member

@timrwood you shouldn't be programmatically running tasks. That is not what gulp is meant to be.

Member

phated commented Jan 25, 2014

@timrwood you shouldn't be programmatically running tasks. That is not what gulp is meant to be.

@contra

This comment has been minimized.

Show comment
Hide comment
@contra

contra Jan 25, 2014

Member

@timrwood If gulp was a task runner I would agree with you. gulp is a build system helper, the task system is out of necessity. We are trying to ween people off of this and onto vanilla JS stuff. JS has an awesome task running system called functions that works really well.

Member

contra commented Jan 25, 2014

@timrwood If gulp was a task runner I would agree with you. gulp is a build system helper, the task system is out of necessity. We are trying to ween people off of this and onto vanilla JS stuff. JS has an awesome task running system called functions that works really well.

@timrwood

This comment has been minimized.

Show comment
Hide comment
@timrwood

timrwood Jan 25, 2014

Gulp may not solely be a task runner, but the fact that it runs tasks kind of makes it a task runner. I suppose this is just a matter semantics though, so I'll just consider gulp a thing that has a task runner.

I think the task system in gulp/orchestrator one of gulp's strengths. Being able to name units of work and reference other named units of work that must happen prior is an excellent pattern.

I understand that you can do essentially what gulp.run did by passing around and calling functions.

The problem I see is that now we end up with is two task systems.

One is formally defined by gulp. It is what is used for running tasks from the command line and from watchers. It has explicit task dependency definitions. It is well tested, and bugfixes are shared with everyone.

The second is informally defined by the user. It may be written with callbacks or events or promises or some other vanilla js. It may or may not have explicit task dependency definitions. It is probably not well tested, and bugs are unique to each re-implementation.

I understand that both of these spaces are going to exist, but removing the ability to start a gulp task from user-land code feels like you are pushing a greater burden onto the user.

Here is a closer representation of what I am currently doing. There are a few more tasks for html, images, and fonts, but this is the gist of it.

var minify = false;

// js-clean and css-clean remove compiled assets
gulp.task('js-clean', function () {...});
gulp.task('css-clean', function () {...});

// js and css tasks use gulp-if to only minify when minify is true
gulp.task('js', ['js-clean'], function () {...});
gulp.task('css', ['css-clean'], function () {...});

// task to build before deployment
gulp.task('build', function () {
    minify = true;
    gulp.run('js', 'css');
});

// task to run while actively developing
gulp.task('develop', function () {
    minify = false;
    gulp.run('js', 'css');
    gulp.watch(jsPaths, 'js');
    gulp.watch(cssPaths, 'css');
});

Without gulp.run, now I need have the develop and build tasks simply call functions that do what the js and css tasks do. But before those functions run, I need to have functions that do what js-clean and css-clean do. Sure, this is possible, but now I have written a one-off task dependency system that cannot hook into gulp's dependency system.

If I want the two to work together, I need to create hooks for the gulp task dependency system to call my task dependency system rather than the other way around.

Again, all this is possible to do, but it just seems silly to have a task runner bundled with gulp that you cannot use for running tasks and managing their dependencies.

If the reason for deprecating gulp.run was because of user error, do you really think making users implement their own solution is going to result in fewer user errors?

timrwood commented Jan 25, 2014

Gulp may not solely be a task runner, but the fact that it runs tasks kind of makes it a task runner. I suppose this is just a matter semantics though, so I'll just consider gulp a thing that has a task runner.

I think the task system in gulp/orchestrator one of gulp's strengths. Being able to name units of work and reference other named units of work that must happen prior is an excellent pattern.

I understand that you can do essentially what gulp.run did by passing around and calling functions.

The problem I see is that now we end up with is two task systems.

One is formally defined by gulp. It is what is used for running tasks from the command line and from watchers. It has explicit task dependency definitions. It is well tested, and bugfixes are shared with everyone.

The second is informally defined by the user. It may be written with callbacks or events or promises or some other vanilla js. It may or may not have explicit task dependency definitions. It is probably not well tested, and bugs are unique to each re-implementation.

I understand that both of these spaces are going to exist, but removing the ability to start a gulp task from user-land code feels like you are pushing a greater burden onto the user.

Here is a closer representation of what I am currently doing. There are a few more tasks for html, images, and fonts, but this is the gist of it.

var minify = false;

// js-clean and css-clean remove compiled assets
gulp.task('js-clean', function () {...});
gulp.task('css-clean', function () {...});

// js and css tasks use gulp-if to only minify when minify is true
gulp.task('js', ['js-clean'], function () {...});
gulp.task('css', ['css-clean'], function () {...});

// task to build before deployment
gulp.task('build', function () {
    minify = true;
    gulp.run('js', 'css');
});

// task to run while actively developing
gulp.task('develop', function () {
    minify = false;
    gulp.run('js', 'css');
    gulp.watch(jsPaths, 'js');
    gulp.watch(cssPaths, 'css');
});

Without gulp.run, now I need have the develop and build tasks simply call functions that do what the js and css tasks do. But before those functions run, I need to have functions that do what js-clean and css-clean do. Sure, this is possible, but now I have written a one-off task dependency system that cannot hook into gulp's dependency system.

If I want the two to work together, I need to create hooks for the gulp task dependency system to call my task dependency system rather than the other way around.

Again, all this is possible to do, but it just seems silly to have a task runner bundled with gulp that you cannot use for running tasks and managing their dependencies.

If the reason for deprecating gulp.run was because of user error, do you really think making users implement their own solution is going to result in fewer user errors?

@phated

This comment has been minimized.

Show comment
Hide comment
@phated

phated Jan 25, 2014

Member

@timrwood for someone that claims Orchestrator is one of Gulp's strengths, it seems that you don't really understand what is happening inside Gulp.

Gulp is just an instance of Orchestrator, that adds an arbitrary run function onto the prototype, which only exists because of the default task. Gulp just decides if you didn't specify any tasks to run, sets it to ['default'] if you didn't and then calls orchestrator.start.

Please note that start is already on the Gulp singleton because it is just an instance of orchestrator and was not deprecated in Gulp or Orchestrator. This is the method you should be using, if you don't think you can implement something with task dependencies, functions and standard JS patterns (I believe all your examples could and should be written better without run or start).

gulp.run will not be undeprecated, as it is not a pattern we want to promote.

Member

phated commented Jan 25, 2014

@timrwood for someone that claims Orchestrator is one of Gulp's strengths, it seems that you don't really understand what is happening inside Gulp.

Gulp is just an instance of Orchestrator, that adds an arbitrary run function onto the prototype, which only exists because of the default task. Gulp just decides if you didn't specify any tasks to run, sets it to ['default'] if you didn't and then calls orchestrator.start.

Please note that start is already on the Gulp singleton because it is just an instance of orchestrator and was not deprecated in Gulp or Orchestrator. This is the method you should be using, if you don't think you can implement something with task dependencies, functions and standard JS patterns (I believe all your examples could and should be written better without run or start).

gulp.run will not be undeprecated, as it is not a pattern we want to promote.

@robrich

This comment has been minimized.

Show comment
Hide comment
@robrich

robrich Jan 25, 2014

Contributor
var minify = !gulp.env.debug;

// js-clean and css-clean remove compiled assets
gulp.task('js-clean', function () {...});
gulp.task('css-clean', function () {...});

// js and css tasks use gulp-if to only minify when minify is true
gulp.task('js', ['js-clean'], function () {...});
gulp.task('css', ['css-clean'], function () {...});

// task to build before deployment
gulp.task('build', ['js','css']);

// task to run while actively developing
gulp.task('develop', ['js','css'], function () {
    gulp.watch(jsPaths, ['js']);
    gulp.watch(cssPaths, ['css']);
});
Contributor

robrich commented Jan 25, 2014

var minify = !gulp.env.debug;

// js-clean and css-clean remove compiled assets
gulp.task('js-clean', function () {...});
gulp.task('css-clean', function () {...});

// js and css tasks use gulp-if to only minify when minify is true
gulp.task('js', ['js-clean'], function () {...});
gulp.task('css', ['css-clean'], function () {...});

// task to build before deployment
gulp.task('build', ['js','css']);

// task to run while actively developing
gulp.task('develop', ['js','css'], function () {
    gulp.watch(jsPaths, ['js']);
    gulp.watch(cssPaths, ['css']);
});
@timrwood

This comment has been minimized.

Show comment
Hide comment
@timrwood

timrwood Jan 25, 2014

@robrich, well, it would have to be gutil.env.debug as gulp.env is being deprecated as well.

It seems like overkill to require adding command line args in order to add any logic before running tasks, but I suppose between gutil.env and Orchestrator#start I'll be able to figure out a workaround.

It's just incredibly frustrating to have 40% of the publicly documented gulp api deprecated at once.

timrwood commented Jan 25, 2014

@robrich, well, it would have to be gutil.env.debug as gulp.env is being deprecated as well.

It seems like overkill to require adding command line args in order to add any logic before running tasks, but I suppose between gutil.env and Orchestrator#start I'll be able to figure out a workaround.

It's just incredibly frustrating to have 40% of the publicly documented gulp api deprecated at once.

@phated

This comment has been minimized.

Show comment
Hide comment
@phated

phated Jan 25, 2014

Member

Gulp is tiny, so saying "40%" is meaningless. If gulp could be nothing, it would be.

Member

phated commented Jan 25, 2014

Gulp is tiny, so saying "40%" is meaningless. If gulp could be nothing, it would be.

@robrich

This comment has been minimized.

Show comment
Hide comment
@robrich

robrich Jan 25, 2014

Contributor

@timrwood I can feel your pain -- gulp is moving incredibly fast. I presented gulp recently, and someone asked, "how old is this project?" It didn't exist at all 6 months ago, and today it's all-but the dominant build system in JavaScript. I can only imagine what it'll look like in 6 more months. If you used the standard enterprise "upgrade every-other version" technique, you'd still be in here at least once a month.

Towards your point about the redundant command-line switch, what if the bug was introduced by the minifier, so you wanted to watch and minify?

Contributor

robrich commented Jan 25, 2014

@timrwood I can feel your pain -- gulp is moving incredibly fast. I presented gulp recently, and someone asked, "how old is this project?" It didn't exist at all 6 months ago, and today it's all-but the dominant build system in JavaScript. I can only imagine what it'll look like in 6 more months. If you used the standard enterprise "upgrade every-other version" technique, you'd still be in here at least once a month.

Towards your point about the redundant command-line switch, what if the bug was introduced by the minifier, so you wanted to watch and minify?

@contra

This comment has been minimized.

Show comment
Hide comment
@contra

contra Jan 25, 2014

Member

@timrwood Use gulp.start then. Basically all that changed by deprecating gulp.run was that I moved the opinion of having a 'default' task to the CLI (which now uses .start()) and we are removing run. It was a worthless layer to begin with - .start works just fine

Member

contra commented Jan 25, 2014

@timrwood Use gulp.start then. Basically all that changed by deprecating gulp.run was that I moved the opinion of having a 'default' task to the CLI (which now uses .start()) and we are removing run. It was a worthless layer to begin with - .start works just fine

@thauburger

This comment has been minimized.

Show comment
Hide comment
@thauburger

thauburger Jan 26, 2014

@robrich and @contra thanks for the concrete alternatives and examples. It's very helpful.

On a larger note, I think @timrwood brings up a very important point to consider here: how end-users understand the semantics of the tool. It's fine to have an internal understanding that gulp is not meant to be a programmatic task runner, but the existing documentation (particularly Mark Goodyear's popular post that is promoted in current gulp docs) doesn't make this clear. While @phated proposes architecturally valid solutions in this thread, that doesn't scale to help new (and existing) gulpers understand the "right way" to use the tool.

A user who legitimately uses gulp.run() today now sees a deprecation warning - without a clear explanation of the deprecation or its alternatives in the documentation. At the same time, a new user is pointed to promoted examples that heavily rely on a pattern that you don't want promoted.

One of the beauties of gulp is the simplicity and intuitive nature of defining build steps. I think it's a fair (and important) thing to call out when changes to the API challenge those qualities for the end-user. While there are great workarounds (and improved patterns) discussed in this thread, I think the true essence of the issue is that it's not yet "clear" from the docs how to replace run() usage with correct patterns.

I found the insights in this thread helpful, and it might help to bubble those learnings up for others like @timrwood and myself.

Thanks for the discussion!

thauburger commented Jan 26, 2014

@robrich and @contra thanks for the concrete alternatives and examples. It's very helpful.

On a larger note, I think @timrwood brings up a very important point to consider here: how end-users understand the semantics of the tool. It's fine to have an internal understanding that gulp is not meant to be a programmatic task runner, but the existing documentation (particularly Mark Goodyear's popular post that is promoted in current gulp docs) doesn't make this clear. While @phated proposes architecturally valid solutions in this thread, that doesn't scale to help new (and existing) gulpers understand the "right way" to use the tool.

A user who legitimately uses gulp.run() today now sees a deprecation warning - without a clear explanation of the deprecation or its alternatives in the documentation. At the same time, a new user is pointed to promoted examples that heavily rely on a pattern that you don't want promoted.

One of the beauties of gulp is the simplicity and intuitive nature of defining build steps. I think it's a fair (and important) thing to call out when changes to the API challenge those qualities for the end-user. While there are great workarounds (and improved patterns) discussed in this thread, I think the true essence of the issue is that it's not yet "clear" from the docs how to replace run() usage with correct patterns.

I found the insights in this thread helpful, and it might help to bubble those learnings up for others like @timrwood and myself.

Thanks for the discussion!

@phated

This comment has been minimized.

Show comment
Hide comment
@phated

phated Jan 26, 2014

Member

@thauburger The dependencies alternative is called out in the documentation. All examples were switched to using dependency arrays because gulp.run and gulp.start are antipatterns within gulp that, when nested, cause never-ending task queues. That isn't something we want to promote within gulp, which is why people will be pointed to orchestrator for more complex patterns, such as this.

At the pace gulp is moving, we can't expect blog posts to stay current, but I suppose we can remove them from the markdown files. I would be happy to take a PR to remove it.

I also think we need more recipes that show how to "just use functions" and that makes me very sad to say because it seems that people that don't understand JS have been picking this up at an alarming rate without understanding what they are getting into.

Member

phated commented Jan 26, 2014

@thauburger The dependencies alternative is called out in the documentation. All examples were switched to using dependency arrays because gulp.run and gulp.start are antipatterns within gulp that, when nested, cause never-ending task queues. That isn't something we want to promote within gulp, which is why people will be pointed to orchestrator for more complex patterns, such as this.

At the pace gulp is moving, we can't expect blog posts to stay current, but I suppose we can remove them from the markdown files. I would be happy to take a PR to remove it.

I also think we need more recipes that show how to "just use functions" and that makes me very sad to say because it seems that people that don't understand JS have been picking this up at an alarming rate without understanding what they are getting into.

@robrich

This comment has been minimized.

Show comment
Hide comment
@robrich

robrich Jan 26, 2014

Contributor

I agree. Please PR in places where the docs aren't clear.

Contributor

robrich commented Jan 26, 2014

I agree. Please PR in places where the docs aren't clear.

@pzi

This comment has been minimized.

Show comment
Hide comment
@pzi

pzi Apr 23, 2014

I came here looking for some kind of simple way to set environment variables for my project. I tried with process.env.var or minimist but ended up doing something like the below and it seems to solve my problem for now:

var gulp = require('gulp'),
  gulpif = require('gulp-if'),
  environment = 'develop';

gulp.task('javascripts', function() {
  gulp
    .src(paths.javascript)
    .pipe(gulpif(environment == 'production', uglify()))
    .pipe(gulp.dest('./js'));
});

gulp.task('set-environment-production', function () {
  environment = 'production';
});

gulp.task('build', ['set-environment-production', 'javascripts']);

While it feels kinda cheaky, it works for what I need and doesn't add a lot of other code or complications to the code.

Glad to hear some thoughts and be pointed towards a better solution.

Thanks.

pzi commented Apr 23, 2014

I came here looking for some kind of simple way to set environment variables for my project. I tried with process.env.var or minimist but ended up doing something like the below and it seems to solve my problem for now:

var gulp = require('gulp'),
  gulpif = require('gulp-if'),
  environment = 'develop';

gulp.task('javascripts', function() {
  gulp
    .src(paths.javascript)
    .pipe(gulpif(environment == 'production', uglify()))
    .pipe(gulp.dest('./js'));
});

gulp.task('set-environment-production', function () {
  environment = 'production';
});

gulp.task('build', ['set-environment-production', 'javascripts']);

While it feels kinda cheaky, it works for what I need and doesn't add a lot of other code or complications to the code.

Glad to hear some thoughts and be pointed towards a better solution.

Thanks.

@laurelnaiad

This comment has been minimized.

Show comment
Hide comment
@laurelnaiad

laurelnaiad Apr 23, 2014

Contributor

Using minimist seems like a nice, clean approach if your goal is to use command line args to set parameters. Why do you want to use a task to assign a value to a module-level variable? It seems like you've added code and complications even though you didn't want to. If you want (environment === 'production') before your build task runs, then there are plenty of regular old javascript ways of making it so. BTW, the code you posted above has you running your javascripts task with (environment === 'development') and your build task with (environment === 'production'). The idea of using a task just to set a variable might be coming from grunt exposure where everything had to be done in a task. This is just a node module like any other. You are free to "roam about" the file and make things happen in the order you want without making them all tasks. Your build task is not prevented from running code in its function (i.e. you needed immediately start with gulp.src in every task).

Contributor

laurelnaiad commented Apr 23, 2014

Using minimist seems like a nice, clean approach if your goal is to use command line args to set parameters. Why do you want to use a task to assign a value to a module-level variable? It seems like you've added code and complications even though you didn't want to. If you want (environment === 'production') before your build task runs, then there are plenty of regular old javascript ways of making it so. BTW, the code you posted above has you running your javascripts task with (environment === 'development') and your build task with (environment === 'production'). The idea of using a task just to set a variable might be coming from grunt exposure where everything had to be done in a task. This is just a node module like any other. You are free to "roam about" the file and make things happen in the order you want without making them all tasks. Your build task is not prevented from running code in its function (i.e. you needed immediately start with gulp.src in every task).

@pzi

This comment has been minimized.

Show comment
Hide comment
@pzi

pzi Apr 23, 2014

Thanks for your answer @stu-salsbury. And sorry, yeah, I may not have provided enough information.

My goal was to have this setup:
$ gulp runs all tasks in 'development' environment in order to easier debug output.
$ gulp build runs all the tasks in 'production' environment and minifies outputs, outputting 'deploy-ready' code. I am using this particularly for a WordPress theme, where the build output is the upload-ready WP theme.

And yes, you are right, I am coming from Grunt :) I just started using gulp a week ago. And with grunt it was nice to have the subtasks (ie. compass:dev, compass:dist).

pzi commented Apr 23, 2014

Thanks for your answer @stu-salsbury. And sorry, yeah, I may not have provided enough information.

My goal was to have this setup:
$ gulp runs all tasks in 'development' environment in order to easier debug output.
$ gulp build runs all the tasks in 'production' environment and minifies outputs, outputting 'deploy-ready' code. I am using this particularly for a WordPress theme, where the build output is the upload-ready WP theme.

And yes, you are right, I am coming from Grunt :) I just started using gulp a week ago. And with grunt it was nice to have the subtasks (ie. compass:dev, compass:dist).

@laurelnaiad

This comment has been minimized.

Show comment
Hide comment
@laurelnaiad

laurelnaiad Apr 23, 2014

Contributor

@pzi I think the policy here is to send this kind of thing to stack overflow.... I' d be happy to take it up with you over there.

Contributor

laurelnaiad commented Apr 23, 2014

@pzi I think the policy here is to send this kind of thing to stack overflow.... I' d be happy to take it up with you over there.

@bfricka

This comment has been minimized.

Show comment
Hide comment
@bfricka

bfricka Jun 23, 2014

@phated, reading through all this, I felt the desire to share an alternative viewpoint regarding your comment:

I also think we need more recipes that show how to "just use functions" and that makes me very sad to say because it seems that people that don't understand JS have been picking this up at an alarming rate without understanding what they are getting into.

I don't view this as "sad" at all, although from a maintainer's perspective I can see how it could be a bit maddening. From my perspective, Gulp--with its popularity and solid patterns--offers a fantastic opportunity to raise the bar when it comes to both constructing build systems, and more generally, writing quality JavaScript.

By mastering Gulp, one is introduced to concepts like streams, buffers, promises, asynchronicity, file system, etc., all very fundamental concepts in the Node world. By creating strict patterns, you are increasing the barrier to entry, but are doing so by expecting knowledge of fundamental concepts, which I think is a good thing.

The knowledge will eventually propagate. There's room for improvement in the docs, for sure, but b/c Gulp is fundamentally better, the community will also begin to pick up the slack w/ tutorials and blog posts.

bfricka commented Jun 23, 2014

@phated, reading through all this, I felt the desire to share an alternative viewpoint regarding your comment:

I also think we need more recipes that show how to "just use functions" and that makes me very sad to say because it seems that people that don't understand JS have been picking this up at an alarming rate without understanding what they are getting into.

I don't view this as "sad" at all, although from a maintainer's perspective I can see how it could be a bit maddening. From my perspective, Gulp--with its popularity and solid patterns--offers a fantastic opportunity to raise the bar when it comes to both constructing build systems, and more generally, writing quality JavaScript.

By mastering Gulp, one is introduced to concepts like streams, buffers, promises, asynchronicity, file system, etc., all very fundamental concepts in the Node world. By creating strict patterns, you are increasing the barrier to entry, but are doing so by expecting knowledge of fundamental concepts, which I think is a good thing.

The knowledge will eventually propagate. There's room for improvement in the docs, for sure, but b/c Gulp is fundamentally better, the community will also begin to pick up the slack w/ tutorials and blog posts.

@raDiesle

This comment has been minimized.

Show comment
Hide comment
@raDiesle

raDiesle Sep 9, 2014

Same mind: mutli-projects needs to be solved with gulp, easily!

This is our current setup:

In Child :

var gulp = require("gulp");
var gulpInit = require("../../../config/gulp/gulpfile");
gulpInit(gulp);

in Parent:
module.exports = function(gulp){
gulp.task("watch", function(){ ...});
// return gulp;
}

raDiesle commented Sep 9, 2014

Same mind: mutli-projects needs to be solved with gulp, easily!

This is our current setup:

In Child :

var gulp = require("gulp");
var gulpInit = require("../../../config/gulp/gulpfile");
gulpInit(gulp);

in Parent:
module.exports = function(gulp){
gulp.task("watch", function(){ ...});
// return gulp;
}

@carlodicelico

This comment has been minimized.

Show comment
Hide comment
@carlodicelico

carlodicelico Jan 13, 2015

@raDiesle I had this problem at work recently. We have 4 large code bases that all need to use the same gulp tasks but with different configs (paths, etc.). What we did is turn all of our gulp tasks into a private npm module which we then install in each project. This way, we can maintain our tasks from one repo and all we have to update per project is our settings file. Our solution works equally well from the command line and from our Jenkins build scripts and we're able to provide a nicer CLI to the gulp tasks for developers.

bin/
    yourmodule
lib/
    main.js
modules/
    gulp-related node modules
tasks/
    gulp tasks
test/
    main.js
gulpfile.js
package.json
README.md

We also make use of gulp-load-plugins and require-dir to make all of this more modular.

carlodicelico commented Jan 13, 2015

@raDiesle I had this problem at work recently. We have 4 large code bases that all need to use the same gulp tasks but with different configs (paths, etc.). What we did is turn all of our gulp tasks into a private npm module which we then install in each project. This way, we can maintain our tasks from one repo and all we have to update per project is our settings file. Our solution works equally well from the command line and from our Jenkins build scripts and we're able to provide a nicer CLI to the gulp tasks for developers.

bin/
    yourmodule
lib/
    main.js
modules/
    gulp-related node modules
tasks/
    gulp tasks
test/
    main.js
gulpfile.js
package.json
README.md

We also make use of gulp-load-plugins and require-dir to make all of this more modular.

@paislee

This comment has been minimized.

Show comment
Hide comment
@paislee

paislee Mar 2, 2015

I found this thread useful for understanding the nature of Gulp: what it is, isn't, and the power of Orchestrator. Wrote about it: http://paislee.io/a-healthy-gulp-setup-for-angularjs-projects/.

paislee commented Mar 2, 2015

I found this thread useful for understanding the nature of Gulp: what it is, isn't, and the power of Orchestrator. Wrote about it: http://paislee.io/a-healthy-gulp-setup-for-angularjs-projects/.

@JasonGoemaat

This comment has been minimized.

Show comment
Hide comment
@JasonGoemaat

JasonGoemaat Jun 2, 2016

"gulp is not a task runner" - Well, that is pretty much what I use it as. There is tooling support in a lot of editors that will let you pick a 'task' from a gulpfile (vim, sublimetext, vscode, ...). It's nice because you can just drop a gulpfile in and create named tasks in JS and easily execute them from the command line or from your editor. I use other tools for the actual building, but I use gulp to call them. Why? They don't have a task running system like gulp does. Not being able to run one task from another seems like a silly limitation to me.

For now I'm having to do a bunch of refactoring because I like it as a task runner, so I end up with methods like this:

function buildDist(done) {
  ...
  done();
}
gulp.task("build-dist", ["clean-dist"], buildDist);`

JasonGoemaat commented Jun 2, 2016

"gulp is not a task runner" - Well, that is pretty much what I use it as. There is tooling support in a lot of editors that will let you pick a 'task' from a gulpfile (vim, sublimetext, vscode, ...). It's nice because you can just drop a gulpfile in and create named tasks in JS and easily execute them from the command line or from your editor. I use other tools for the actual building, but I use gulp to call them. Why? They don't have a task running system like gulp does. Not being able to run one task from another seems like a silly limitation to me.

For now I'm having to do a bunch of refactoring because I like it as a task runner, so I end up with methods like this:

function buildDist(done) {
  ...
  done();
}
gulp.task("build-dist", ["clean-dist"], buildDist);`

@gulpjs gulpjs locked and limited conversation to collaborators Jun 2, 2016

@contra

This comment has been minimized.

Show comment
Hide comment
@contra

contra Jun 15, 2016

Member

Just to be clear: the new task system in 4.0 is leagues ahead and much more flexible than the 3.x one discussed in this thread. Check out the docs on the 4.0 branch, you'll all love it!

Member

contra commented Jun 15, 2016

Just to be clear: the new task system in 4.0 is leagues ahead and much more flexible than the 3.x one discussed in this thread. Check out the docs on the 4.0 branch, you'll all love it!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.