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:
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.
I'm not sure why people are afraid of Makefiles. I know an incredible number of developers who view them as this scary black box. They are not a heavy weight thing which justify making excuses about not producing.
Here's what it takes to make a new Javascript project:
Unless you're jQuery, you don't need minification or GZipping because clients of your library already have their own. You don't need your own linting because you can trivially run `jshint project.js`.
If you find yourself running the same command in your shell a bunch of times, add it to your Makefile. It's that simple.
As someone who is not afraid of Makefiles (and has used them by default in past JavaScript-based projects), I welcome tools like Grunt to my projects. It fits in well with the types of "build" tasks I'm typically invoking in my JavaScript projects — and done so in a much simpler and abstracted syntax I prefer to work with.
Also, based on your comments, I think you and I have different definitions of "simple". :)
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.
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.
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.
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.
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.
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.
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.
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.
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:
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.
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.
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:
And generalize your minification using a pattern rule, here's ours: Then add in a gzipping rule: You could trivially stick that sort of thing into `grunt.mk`...And here's how you'd use that:
That said, sometimes it is nice to add some "tasks" for discoverability & encouraging their usage: What if you want to run a subset of tests? Or lint with particular flags? Run a shell command like this one: Then copy paste and edit the output!Simpler is better.