top | item 3776527

Introducing Grunt

179 points| sant0sk1 | 14 years ago |weblog.bocoup.com | reply

28 comments

order
[+] snprbob86|14 years ago|reply
I'm not sure I understand the value of this project at all.

He says that maintaining a monolithic Makefile doesn't scale, but that seems unlikely considering how far BSD stretches Makefiles for it's ports system. Sure, Make has some rough edges, but I don't see how Javascript is possibly preferable for gluing together build processes.

The fundamental problem here is that "task based build system" is a silly idea. Make isn't a programming language, you don't define function names. Make is a dependency graph with files for nodes and command lines for edges. We already have a system for "tasks": stick things in ./script or add things to PATH!

By all means, make a metapackage for your test, lint, etc scripts, but define your concatonation like this:

    out/foo.js: banner src/foo.js
        cat $^ > $@
And generalize your minification using a pattern rule, here's ours:

    %.min.js: %.js
        $(yui) --type js --nomunge < $< > $@
Then add in a gzipping rule:

    %.gz: %
        gzip --best < $< > $@
You could trivially stick that sort of thing into `grunt.mk`...

And here's how you'd use that:

    include grunt.mk

    my-app.min.js.gz: my-app.min.js

    my-app.min.js: $(find src -name '*.js')
That said, sometimes it is nice to add some "tasks" for discoverability & encouraging their usage:

    include grunt.mk

    .PHONY: all lint test

    all: my-app.min.js.gz lint test

    my-app.min.js.gz: my-app.min.js

    my-app.min.js: $(find src -name '*.js')

    test:
        ./test/run

    lint:
        ./script/lint src
What if you want to run a subset of tests? Or lint with particular flags? Run a shell command like this one:

    $ grep test: -A1 Makefile
Then copy paste and edit the output!

Simpler is better.

[+] rmurphey3|14 years ago|reply
You are right, all of this can be done via makefile ... assuming you know how to set up a makefile and take the time to do so. Part of the goal of grunt, as I understand it, is to make it so developers have fewer excuses for not doing this -- setting up a project of a certain type becomes a one-liner. To me, that feels a whole lot simpler than suggesting that developers create the makefile you propose. More often than not, such suggestions result in projects that have no makefile at all -- and thus no tests, no minification, no linting, etc. If grunt helps developers integrate those best practices more easily, that feels like a good thing to me.
[+] MatthewPhillips|14 years ago|reply
I agree. I suck at coding Makefiles but I can't imagine using anything else and never bought Rakefile or Cakefile. I really don't want my build process to have dependencies.
[+] mmj48|14 years ago|reply
(completely off topic)

for the rule:

       %.gz: %
wouldn't you need something like patsubst? Regardless of your response, could you share more info?

edit, that rule above only makes sense to me if the file name to be gzipped was passed to make. Is that correct? (I'm new to make)

[+] justauser|14 years ago|reply
Does anyone else have trouble reading the website with the background/font style or am I just realizing the gifts of middle-age?
[+] 83457|14 years ago|reply
Are you on chrome? I just opened in firefox and it is easier to read. There may be multiple factors here but I have issues with some fonts in chrome being nearly unreadable without increasing font in browser until they essentially present as bolded.
[+] hexis|14 years ago|reply
I have trouble with it at the sprightly age of 33.
[+] steyblind|14 years ago|reply
Snap a screenshot; let us see what you see
[+] arturadib|14 years ago|reply
I think Grunt is great for a lot of projects because it offers out-of-the-box solutions for most common needs.

However, at Mozilla's PDF.js we needed more flexibility - there were so many JS packaging tools out there, each shining for specific purposes, but none general enough for our needs.

So I wrote a port of Unix shell commands (including a Make-like tool) for Node.js which works across platforms:

http://github.com/arturadib/shelljs

The downside is that we don't offer Grunt tools out-of-the-box; the upside is that the tool is more general and (if you already speak Unix shell) you don't have to learn a new framework.

Again, superb work!

[+] ender7|14 years ago|reply
This is a great idea for deployment; I really want someone to write something that helps with development.

Example: I'm using Coffeescript/Closure/whatever as well as LESS/SASS/Stylus as well as some javascript package system. Whenever I change any of those files, I want the appropriate compiler to get run. I might want to then cat all of the output files into a single big file (e.g. main.css). Now I can edit-refresh in peace.

But now I'm done developing, I want to test and deploy. Now I really want that minification. Perhaps I want require.js's optimzation binary to run. Anything that wasn't cat'ed together should get cat'ed now.

Sure, you can make this two separate tools, but I'd rather have just one.

[+] necubi|14 years ago|reply
I wrote a tool along those lines: http://github.com/mwylde/slinky.

It runs a static file server that transparently compiles resources as they are requested (so you request main.js and it finds main.coffee, compiles it, and sends it back).

Then when you're ready to deploy, it's one command to compile/concatenate/minify your css and javascript.

Right now it only supports Coffescript, SASS and HAML, but adding additional compilers is really simple.

[+] groby_b|14 years ago|reply
So, basically, "make"? ;)

The problem with pretty much all build/deploy tools is that they are "just one". There are different tasks, and they _should_ be split.

* Monitoring a filesystem for changes. * Traversing a dependency graph, and computing the minimal set of tasks from there * Execute arbitrary user actions for each task. (For bonus points, allow a feedback channel from actions to DAG) * For extra bonus points, monitor your actions on the OS level to update the DAG automatically. It's neat gcc can create a list of includes. It'd be much neater if I automatically could get a list of dependencies for any tool I run.

Making them into one monolithic tool means inevitably there are some cases the tool is less-than-useful.

[+] ben_alman|14 years ago|reply
There's a built-in "watch" task, along with an open issue to further refine and document it. It's works very well so far, in that a developer can edit arbitrary files and have them all re-linted, unit tested, concatenated, etc as soon as they are saved.

And you could easily have a set of "dev" watch tasks configured, along with "deploy" tasks for minification, etc. There's a lot there, and if you want more just file an issue and we can see what makes sense to implement.

[+] alexobjelean|14 years ago|reply
There is already a tool which has all the features you need to help web developers: http://code.google.com/p/wro4j/wiki/Features

It can be used during development, as a runtime or buildtime solution. Also it can be used as a command line tool. It supports almost all known processors (less, sass, coffee, etc) and allows static code analysis with jshint, jslint or csslint.

[+] dristic|14 years ago|reply
At our studio we use Eclipse and you can add build preferences when saving a file. We built our own bash/shell scrips and just set them to run every time we save which compiles and minifies our script on the spot.

You could easily create a script that ran "node myfile.js" every time you saved.

[+] mcrider|14 years ago|reply
This is pretty great. One suggestion I might make is to allow grunt to automatically create a Git repository and also automatically create a remote repository (Github or private server) to push to. Not that that is hard, its just another boring step that can be made easier by a framework.
[+] erylan|14 years ago|reply
Tough crowd.

Personally I say big ups and thank you.

[+] twalling|14 years ago|reply
I've been using it for over a month or so now and love it.