Closed quangbuule closed 7 years ago
The main difference is code style, in Gulp you use the streaming concept and in Fly this done using the generators and promises ?
@riston Correct.
@quangbuule Thanks for the question. Fly is still a newborn, and there are many plugins that need to be written as well as improvements to make, but here are some of Fly features:
this
is bound to the Fly
instance inside tasks (like koa.js).Small cognitive load. (See here).
Compare to MAKE
Fly.prototype.target
).Currently tasks are generators powered by a macro co-routine. You can yield
your own async functions that return promise/s while still having the flexibility of creating pipeline sequences with filters and transformers. Out of the box.
Fly does make some opinionated assumptions (concat
, watch
, clear
, etc, are all built-ins), however, it is definitely not a magical system.
If you looked at the Flyfile and thought it was magical, is because you have been coaxed into believing build files have to be in a certain way. Fyfiles are simple because Fly's API model is based on the powerful idea of promises.
Some convenient default behavior like loading your imported fly-*
plugins automatically and watching over the default
task (if you don't specify which tasks to watch) does add some sugar, but this is not set in stone, if the community does not like this, it can go away.
I will limit the debate to gulp, arguably the most popular build system out there in the node community. Other systems like Grunt that favor configuration over code, let's not discuss this time.
Some people praise gulp for using streams, but streams are also a complex abstraction. There are transform wrappers out there like through
and may I pitch in my own kthulhu
that help, but I find having to deal with all this when writing gulp plugins dreadful. Fly has no additional abstractions like vinyl
either, which one needs to know at some point if you are writing non trivial plugins.
But I think most plugins should be straightforward wrappers for whatever utilities you are trying to incorporate into the build system. A build system should deal with the complexity of streams, promises, processes, you name it, for me, and even in large systems my build tasks should be no more than one page, because if you end up doing too much, you may as well automate your tasks with shell / npm scripts.
Now, in Fly, sometimes you don't even have to write a plugin, just wrap your transformer function with Fly.prototype.filter
(or Fly.prototype.defer
if you have an async function):
exports.map = function* () {
yield this
.source("strings/*.txt")
.filter((s) => s.toUpperCase())
.filter((s) => s.split("").reverse().join(""))
.target("strings/out")
}
Not trying to cause any discord here, so take the following with a grain of salt, gulp-mocha
is ~ 60 LOC + several dependencies, on the other hand fly-mocha
is less than 15 LOC and just the one necessary dependency, it's also written in ES5 (slightly more verbose than ES6) and still likely to get simpler. Definitely, not a perfect comparison, but it hints at something.
One more thing I am proud of Fly
is that it favors a functional coding style, whereas gulp is flat out the king of imperative code with callbacks and plenty of mutation. I try to avoid let
, using const
instead and the assignment operator =
only for initialization. There are no for
, while
, break
, and mutation is scarce. Current plugins follow this convention as well, although there is still room for improvement.
Another thing is that while gulp is indeed spot on with the streaming metaphor, there are tasks like code analysis, linting, testing, etc., that do not fit this reasoning as well as transforms do. Once again, take gulp-mocha
as an example:
var gulp = require("gulp"), mocha = require("gulp-mocha")
gulp.task("default", function () {
return gulp.src("test.js", { read: false }).pipe(mocha({ reporter: "dot"}))
})
Here is how you roll with Fly:
exports.default = function* () {
yield this.source("test").mocha({ reporter: "dot" })
// yield another.promise
}
Great write up! I've been looking for new build system because gulp-*
installations take an insane amount of time with an obscene amount of dependencies.
Quick question, if were using ES6 here, why not the use it's module system? Instead of:
exports.default = function* () {
// ...
}
Why not:
export default function *() {
// ...
}
// And
export function myTask* () {
// ...
}
@adriancooney modules is not supported on node.js yet.
While Fly is itself written in ES6, it does not require you to use ES6, but you could.
@adriancooney Sure! If you are already using ES6 that is, but since Fly also supports node >= 11
I decided to write the documentation in ES5 first.
Do notice that ATM there is no builtin support for this, so you need to transpile your Flyfile with Babel for example. Having this feature out of the box would be kind of nice though and its implementation would be trivial as well...
Roadmap!!
@quangbuule, @bucaran I see now, that was actually quite a silly question! Great job on this guys, looks great. I'll be giving it a shot in my next project.
Unlocking this issue. If anyone has any questions regarding Fly's philosophy, goal, purpose and whether it deserves to be taken seriously or whatnot, please leave your comments / thoughts below.
@bucaran This was a useful issue to read through, especially your detailed answer. Perhaps link to it or a blog post covering "Why Fly" or "Fly vs Gulp", it would be interesting to see how a full featured Gulp 4 vs Fly file compares. Perhaps there are some projects with large/complicated Gulp tasks that Fly can shine in comparison too, much like how Gulp did to Grunt.
hey, first of all, thx for fly, I'm totally thrilled. After an odysee through trial-n-error (grunt, gulp, jspm, browserify and what-not) it took me under 5min with your examples, to get a 'scss-src to css-out incl. watching' done. It was a breeze and it's fast. Don't tell us, there's no magic behind ;-)
Unfortunately now I got stucked with the babel-example from the examples-folder:
- SyntaxError: bar.js: Unexpected token (1:6)
- > 1 | async function later () {
- | ^
- 2 | await new Promise((cb) => setTimeout(cb, 1000));
- 3 | }
any help appreciated.
In any case. I'll keep on building with fly. Ease of use from my scss-experience convinced me. No more words needed and more important, no googling through the dev-jungle. ;-) And I really believe, I'll get this babel-thing done. Fortunately I saved an immense amount of time on the scss-part ;D
cheers achim
@vedam Thanks. Can you confirm any examples work at all? What about the babel sample?
@bucaran As described above.
I installed fly global:
npm install -g fly
and it took me under 5min with the css-sample to got it working with scss
Then I tried the babel-sample:
copied the folder and inside done the:
npm install
as I tried fly
I've got the error you'll see above.
I've changed nothing on the files. Just the babel-sample as is.
don't want to pollute comments with the whole error msg: https://gist.github.com/vedam/05399162295984f315ab
thx in advance
Closing because is outdated & should be answered by Readme content
Can you please tell me why I would use Fly? I am using gulp now. Thanks.