I hate Node.js

Node.js is cool, so they say. Everybody’s doing it, so I hear.

I hate it. Node.js has wasted so much of my time, I don’t think I will ever forgive it. But take that with a grain of salt. I don’t use Node.js for its intended purpose, which is server-side Javascript.

What I want is a scripting environment for automation on the local machine. In this particular case, I want to script an FTP session from my bash prompt, I want to script a directory sync. I know I can do this with bash scripting, but I already know Javascript syntax and semantics, so I’d like to use what I know. It’s FTP in this case, but in general I want to be able to script arbitrary things on the local machine.

By the way: I can do this on Windows. I can run Javascript programs from the CMD shell, to script an FTP session, automate filesystem operations, launch applications, and a bunch of other things. It’s really nice. There’s a whole catalog of COM objects that can be scripted, including obscure stuff like the fax system in Windows, or more mainstream things like IE settings (like proxies), or IIS administration. Tons of things.

Of course I could do similar things with Node.js on MacOS, too. The problem is, the Node.js model is designed for server use. Everything is asynchronous. When I retrieve a set of files from an FTP server, and I want to iterate and retrieve each file, I have to do that asynchronously. But I don’t want it to be asynchronous. Writing asynchronous code lets me get really good throughput on a server. Writing asynchronous code for my purpose just obscures the goal of the code. I want to do this:

    fileList.forEach(function(item) {
        var modTime = ftp.getModTime(item);
        if (modTime > lastUpdate) {
            ftp.retrieveFile(item);
        }
    });

But I can’t do that. No sir. No I cannot. I’m using Node.js. And because of that, I need this:


    var c = 0, L = flist.length,
        checkIfDone = function() {
            c++;
            if (c == L) { next(); }
        };

    fileList.forEach(function(item, ix) {
        var localPath = (dir == '.') ? item : Path.join(dir, item),
            stat, localMtime = ...,
            remoteMtime = 0;

        // get modification time of the remote file
        sync.ftp.raw.mdtm(localPath, function (e, res) {
            var d, tm;
            if (e) { }
            else {
                remoteMtime = new Date(res);
                if (localMtime == 0 || (remoteMtime > localMtime)) {
                    // Retrieve the file using async streams
                    sync.ftp.getGetSocket(localPath, function(e, sock) {
                        if (e) return console.error(e);
                        var fd = fs.openSync(localPath, "w+");

                        // `sock` is a stream. attach events to it.
                        sock.on("data", function(p) {
                            fs.writeSync(fd, p, 0, p.length, null);
                        });
                        sock.on("close", function(e) {
                            if (e) return console.error(new Error("error"));
                            fs.closeSync(fd);
                            checkIfDone();
                        });

                        // The sock stream is paused. Call
                        // resume() on it to start reading.
                        sock.resume();
                    });
                }
                else {
                    checkIfDone();
                }
            }
        });
    });

Can anyone ELSE see why I’d rather not use an asynchronous-optimized, server-oriented programming environment to script my desktop?

It’s not Javascript that’s the problem here. I can grab the v8 Javascript engine and use it to run JS code. That works. The problem is that there are no JS libraries for v8. There’s no FTP library. There’s no “any” library. The only FTP libraries I’ve found are Node-compliant. To use it, I have to do Node.js things. Likewise for all the other purposes. There’s no package manager for JS libraries, except for Node.js.

I think the solution here is for me to learn to use Bash scripting and use CURL. But that’s a lame solution. It would be nice if MacOS supported Javascript for client-side use, as nicely as Windows does. Because I hate Node.js.



Developer , ,

7 comments


  1. Jameson

    Well, your post sounds like complaining about a spoon when you needed a knife. You might want to take a look at Python – which gives you a cross-platform tool for local scripting and has a lot of batteries included (such as FTP client classes, etc etc). Enjoy.

    • dpc

      Jameson, I think you’re right. I’m complaining that my spoon is not a knife, an there is no (JavaScript) knife. You’re telling me that there are knives, but they require a different programming language. I think your advice is good and I should convert to python, or bash, or some combination.

      • Kyle

        Python = Awesome for this.

        On Windows, Powershell is very nice and has familiar C-syntax…I’ve done a lot with this.

        If you insist on Javascript (I often do)….use Rhino…you write Javascript code and it comes with the entire Java class library so you can pretty much do anything you need to.

  2. Jane

    Im with Jameson.. You need the right tool for the job, node.js was never design to be used in the way you would like to use it.

    Either use python, or ruby with rake, which is my favourite way to automate tasks on windows. Whether or not you know pyhton or ruby, if you are already a programmer, then your ftp script should take no more than an hour or two to complete..

  3. ed

    You do realize you can specify synchronous calls right?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>