Closed alvint closed 9 years ago
I agree with @geekflyer (I think I said this earlier too) - runtime lookups will make organizing gulpfiles into multiple files wayyy easier but it isn't the only way to do it.
ES6 module syntax looks interesting if it's available some day. There's named and default exports. http://24ways.org/2014/javascript-modules-the-es6-way
I made a module to allow forward references to tasks againt this Issue.
It stores the task names and the arguments of gulp.series/.parallel functions when they failed, and try to define the tasks again later in gulp.task function. And it can list failed and undefined tasks with .fails and .undefs functions.
It's an independent module, so it can be removed easily when string name are obsoleted.
@heikki ECMAScript 6 modules looks quite interesting, and the Node side is the perfect place to be an early adapter. Any idea for the timetable on Node.js incorporating it? My guess is many in the Node camp are also in the "ECMAScript 6 is trying to turn JavaScript into Java" camp so support of it may be tepid for a while.
@heikki @alvint . Yeah ES6 module syntax looks nice, but would that have any impact on the forward referencing? I think the current commonjs module system is already very similar to ES6 modules.
I just tried to implement this and I remembered why we can't do it:
The task listing methods we are adding that show the structure of your dependency tree would need to execute the tasks if we only built the tree at task runtime. By building the tree during gulpfile execution we have the entire tree without executing any tasks, which is the desired behavior if you are running gulp with --tasks
flag. We are exposing all this information at the CLI because a lot of tools are adding gulp integrations and we want them to have as much information as possible (we are even exposing a --tasks-json
flag for easy programmatic use). If we executed tasks to build the tree, it would be a very bad thing for these tools, imaging randomly having your dist cleaned on startup of your IDE.
I want to keep string definitions (easy to support) but encourage named function usage (easier to compose)
@geekflyer No impact on forward referencing. Just shooting the breeze. :)
@phated I don't think we need to run the tasks to build the tree...
example
gulp.task('default', gulp.series('task1', 'task2'));
gulp.task('task2', gulp.series('task1'));
gulp.task('task1', fn);
if you wait until execution of a task before calculating the dependencies in gulp.series, you will never know that task2 relies on task1 without executing task2.
@phated Won't you have that issue regardless of whether you have forward references, and no matter how you figure out the task names (with labels or by using named functions)?
@alvint no, the stuff we currently have works
Then from a CS/logic standpoint it must be doable with task names as well. You're just sticking additional functionality on top.
I'm going to close this topic as it has already diverged multiple times. I am not going to be working on this feature and if someone wants to contribute actual code instead of bikeshedding it into oblivion and killing my will to work on gulp4, I will happily review the patch.
@phated What do you mean with "executing a task" ? Can't we simply implement a logic for gulp.task, gulp.series and gulp.parallel, so that the arguments (functions) are only executed for --task listing lookup when they are the output of gulp.series or gulp.parallel?
@geekflyer i welcome you to read the gulp4 code to understand. feel free to submit a patch
Ok, I'll give it a try :-)
I am not going to be working on this feature and if someone wants to contribute actual code instead of bikeshedding it into oblivion and killing my will to work on gulp4, I will happily review the patch.
@phated Please try to maintain an inclusive environment for people who want to contribute.
@contra I believe I was being inclusive in saying that I am looking for help in this matter. I won't be implementing this as I don't see any way to do it that makes sense. More bikeshedding without code doesn't move the project along.
@phated didn't @sttk have code?
@phated In any case I'll write it. Just give me your requirements (what you wan't the interface and any API contracts to look like).
All the code is there and you seem to be defining the requirements.
@phated You mentioned something about wanting to be able to list dependencies? How do you want that to work exactly?
@alvint the gulp --tasks
, gulp --tasks-simple
and gulp --tasks-json
commands all currently work as desired in the 4.0 branch. It needs to continue to work the same.
Figured I would update this post. It was easiest to implement forward references as a custom registry - see https://github.com/undertakerjs/undertaker-forward-reference
This makes migration to v4 much more time-consuming than it needs to be.
what's the point of a registry if everything needs to be defined in order?
I'm defining tasks here, with names as strings. I expect them to exist.
My fear with that approach is that users will see in G4 a product that is too different from the product they're already used to and like,
Upon discovering this, I'm ready to stick with v3 for the next 6 decades.
This might be a more significant problem in some cases than it appears. Sometimes tasks come from other systems and might consist of objects containing task name and function. Those aren't guaranteed to be in order in javascript.
This means having to do really weird things with the structure to get things to work.
Currently, forward references to tasks do not work in gulp 4 (and gulp 3, but I don't care about that):
This results in
AssertionError: Task never defined: clean
.From a stylistic standpoint, many people prefer to place the broadest tasks first and then define component tasks later, since this is how most people think and design code. Also the current 'bottom up', Forth-like restriction is no longer necessary considering how gulp 4 works.
From a design standpoint, since tasks are interchangeable with functions now, and since functions (like most stuff in Javascript) can be referenced from anywhere within the current scope regardless of where it was declared, to be consistent tasks should work the same way.