Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Fez, a file-based build tool for JavaScript (isaacbw.com)
70 points by isaacb on Jan 20, 2014 | hide | past | web | favorite | 26 comments

If you're interested in file-based tools, Jake [1] has excellent support for the sort of rules Fez of offers, and is quite mature.

I haven't dug deeply into Fez yet, but here's a few things Fez seems to offer that Jake doesn't:

1- Automatic concurrency. Like Gulp, Fez's subtasks run in parallel. It looks like Fez launches them in subprocesses in order to prevent conflicts, which is a good idea. I'm skeptical of parallelism in builds, though, because race conditions lead to nasty, hard-to-detect-and-fix bugs. I don't think the theoretical speed boost is worth the potential of defects getting into released code.

2- Automatic pipelining. Also like Gulp, Fez can pipe the output of one operation to the input of another. This is useful because you can avoid dealing with temporary files. Unlike Gulp, Fez has an extremely simple and non-error-prone way of constructing those pipelines. I like it.

The major advantage of Fez (and Jake) over Grunt and Gulp is that they use file timestamps to tell if a task needs to run. This can lead to major speed benefits. I recently modified my Jakefile to use this sort of dirty checking on my Sass compiler. I don't change my CSS that often, but the css task was doing an expensive "shell to Ruby" command on every build no matter what. Adding dirty checking shaved my typical build time down from 6.5s to 3.5s.

Overall, Fez looks like a really nice tool. It has a strong ideology (rule-based transformation of files) tempered by a nice dose of practicality. For example, although Fez wants every task to define a file-transformation rule, it also supports "imperative mode" for tasks that don't fit that model. It's very promising, and I'm looking forward to learning more.

[1] Jake: https://github.com/mde/jake

I'm suppose I'm in the minority of developers that _don't_ think we need to learn more build tools.

make, configure, automake, autoconf, MSBuild, Apache Ant, rake, gradle, jake, grunt, gulp, fez

Sorry, I'm sure your system is nice and organized. But now you've introduced one more build dependency that will make projects based on Fez just a little more difficult to on-board.

I couldn't disagree more strongly. Sure, make is a fine (if quirky) tool, but I would hate to live in a world where that was the only build tool available. There's good reasons people choose not to use it.

Fact is, people want different things from their tools. Each of the ones you mentioned has its own strengths and weaknesses. They tend to be better than their predecessors in some way, for some specific need. And this is how progress is made... via a thriving marketplace of [ build tools, languages, frameworks, libraries ]. I wouldn't have it any other way.

One of the great things about open-source, is when you discover a weakness in some tool you like, you can modify that tool and submit a patch. Or you can learn from the source of one tool and add another tool to the marketplace. When the marketplace is saturated, patching or modifying the popular tools is preferable to me.

Also, I would prefer developers spend more time making general applications and less time making tools for other developers. I'm not saying people shouldn't make great dev tools, I'm saying more people should make great applications, and less people should make great dev tools.

I agree, it's great to be able to fix problems with open source projects. But there's not always one tool to rule them all

Fact is, people want different things from their tools.

I wonder what the pros/cons are for Fez, compared to Gulp: https://github.com/gulpjs/gulp

Fez looks a lot more promising than Gulp to me:

1- Fez is more pragmatic. It has a strong ideology, but it also tempers that with escape hatches for when your needs don't fit that ideology.

2- Fez's pipelining is really simple and elegant. Gulp's pipelining is verbose and it's easy to forget to return the stream, which leads to race conditions.

3- Fez has dirty-checking so it won't run tasks on files that are up-to-date.

4- Task functions look much simpler to write (and thus, less error-prone).

I haven't tried Fez yet (and I have tried Gulp [1]), but I like what I see.

[1] My review of Gulp (wait for the comments to load): http://www.letscodejavascript.com/v3/comments/lab/1#comment-...

I am in the process of creating a build tool too (for a different language: Java) I noticed that you have some magic variables (%f), like make ($<, etc..). I am trying to avoid that, but I cannot come up with a clean way without 'magic' variables (e.g. When using wildcards, one would need to know the set of files that have changed. Mine is something similar to

  classes/**/*.class -> src/**/*.java:
      javac [WHAT TO USE IF NOT A 'Maigc var'?]

1. Will fez support different dir for target and recipes? (like above example I gave) ?

2. What about targets that do not have a file dependency (e.g. .PHONY in make)? How does fez deal with it?

What I am trying to avoid is a big learning curve (or have a user need to read a book) :-)

Thank you and success in your project!

I don't understand how to use it. Can I just write this:

    *.less → %f.css
    *.css → %f.min.css
    *.min.css → dist.min.css
in a file and then run the command "fez"? And if not, then why not? If that was how you used fez then I would strongly consider using it.

If you are looking for a build tool, I strongly recommend you first consider a bash script.

Or if you are still looking for a build tool, like you collect them or something, I made my own too (lol): https://github.com/ithkuil/bild

Mine uses yaml files like this:

    - coffee:
        files: src/*.coffee
        out: lib
    - uglify: 
        files: public/js/*.js
        out: public/js/min.js

This is exactly how harp works. If you don't want to deal with configuration harp implicitly does what you just suggested. You can run it directly as a web server or compile your project to HTML/CSS/JS. It might be what you are looking for.

This could turn out to be incredibly powerful tooling for Javascript compilation.

I'm not a fan of Require-type systems because they introduce additional runtime behavior. With the proper dependency graph tools available at compile time, we could remove the need for AMD completely. This will reduce client overhead and boilerplate. (Granted, AMD boilerplate will be converted into a dependency graph spec. But it would be there regardless, and I am of the opinion that this is a superior form.)

Exciting times ahead...

Similar to Bud: http://github.com/azer/bud (https://medium.com/p/6a4c74b4bd90)

See how Bud approaches building and watching changes; https://gist.github.com/azer/7819664

Cool! I have two questions: does this support watching files to regenerate them?

Second, one of the main features from my similar project (npm install webapp-builder) is appending a socket.io connection to generated HTML to force a browser refresh when files have finished building. I view webapp-builder as too monolithic, so I'm curious how difficult it would be to implement a similar feature in Fez?

1) Since it only does the work that needs to be done, you can safely 'watch node fez.js' and if there have been no file changes, nothing will be done! This won't work on Windows, of course, but then I'm not sure if anything else in Fez works on Windows anyway. I'll have to get that going here soon.

2) You can do pretty much whatever sort of transformation you want in an operation. In fact, if you want I can take a look at your code and implement that socket.io appending feature with Fez myself just to show how it can be done.

Thanks for the info. It's not super hi-pri for me right now, but I've starred the project and I'll drop by the IRC channel once I decide it's time to do more work on webapp-builder. Seems like the auto-refreshing bit might make a nice Fez builder (or step, or whatever the lexicon is).

Can someone compare and contrast this with Make?

Pretty cool! Does it track dependencies of build steps that have "require"? E.g. if I have a javascript bundle being built using browserify - will it track the files that browserify is loading? Also: Did you consider reusing the Grunt ecosystem? E.g. enable loading grunt plugins and treat this as a potential alternate runner?

Looks interesting. A note to the author: that post is very difficult to read on mobile. Setting a width on your container will go a long way to improve readability (e.g. .wrapper { max-width: 90%; margin: 0 auto; }).

Fixed! Thanks for the heads up.

How does this compare to something like Brunch? http://brunch.io/

I haven't seen Brunch before, but it still seems to suffer from the same major flaw as Grunt, which is no sense of file-file relationships:

"Brunch recompiles and concats all your stuff automatically on any change, headlessly. No more need in compicated Makefiles and watchers."

Perhaps I'm wrong, but Brunch just seems like a variant on Grunt with a lot more out of the box for building front-end web applications.

Still, it does look cool. Thanks for the link!

BTW, fezes is faeces in portuguese ;)

Hah! I should probably change it to Fezzes then.

Also, there's a popular video game also named "Fez" which uses the same fez hat in it. It probably won't lead to confusion since the game isn't a file based build tool, though it'll be something you might have to indirectly compete with in search results. :)

While Fezes, as (s)he said means faeces in Portugues, FEZ does not mean that. It actually means:

   1. Did 
   2. Made 
   3. Built
From the verb FAZER (to build, to do, to make), third person (ele/he) of 'Preterito Perfeito do indicativo'

You could change it to "fes", the original name of the hat in Turkish =)

Applications are open for YC Winter 2020

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact