I made a couple of small node.js modules to help me develop couchapps.

CouchApp is two things: a concept and a tool. The concept is an application that runs on CouchDB, using its API. The API has three basic components for presenting data (it has others for editing data but that isn’t covered in this post):

  • views: A view in CouchDB is a Map and optionally a Reduce function, which enables indexing JSON documents using the powerful MapReduce programming model.
  • lists: A list is a function that renders documents from a view, into an any format (commonly HTML).
  • shows: A show function renders a single document, into any format.

With these simple functions, a blog or a photo gallery can be made viewable. The URLs can get a bit awkward, but CouchDB provides a rewrites feature to solve it.

These functions go into a CouchDB design document. CouchDB is a JSON database, and a design document is a JSON document that contains functions as strings. A single design document, with attachments for CSS, which can be served directly to the web browser, can provide access to data without relying on client-side JavaScript (instead using server-side JavaScript).

The tool is a python command-line utility that maps a CouchDB design document to a directory structure. It can clone a design document directly from the database. It breaks it into a lot of little files, including a separate JavaScript file for each function.

This can be a lot of files, when there is one file for each function. Here is the CouchOne pages wiki CouchApp. It has a lot of views.

Mikeal Rogers had perhaps the first solution to this problem: node.couchapp.js. It runs on node.js and allows programmatic building of a design document, and puts functions in strings to prepare the JSON using Function.toString(). This loses the python CouchApp’s advantage of being able to go back and forth from file to CouchDB without losing anything.

I wanted something that could sync back and forth and is more like the original JSON than python’s CouchApp. To make it usable, I need functions shown across multiple lines with syntax highlighting. My hack was to convert the JavaScript to JSON. With CommonJS I can convert JSON to JavaScript easily, just by adding module.exports = to the front of the file. I can then replace the function strings with the direct value of the strings. To go from JavaScript to JSON I need to get the original function source. With JavaScript’s fn.toString(), where fn is a function, I get the source without the comments. I want the comments. It also isn’t indented properly. With Esprima I wrote code to extract the raw function source and fix up the indentation. Examples of this are in the READMEs of the two projects, json2js and js2json.

The projects below are still in early development and barely tested, but I’m putting them to use right now, by finally putting one of my fancy domain names to good use. ;) In the meantime, if this interests you, please check them out and give me feedback.


6 thoughts on “js2json and json2js

  1. This is a great idea, however I have a couple of remarks:

    1. This only works if commonjs modules (“module.exports”) are used, which seems to be an unnecessary restriction. I, for one, do not organize my code that way.

    2. js2json and json2js fit well into the same project, since one assumes as input the output of the other. The separation may lead to compatibility problems.

    • How do you organize your code? I was already thinking about RequireJS support. I’ll make an issue on GitHub.

      I agree that they could fit well into the same project, especially because now they both depend on falafel. I’ll work on a name and a CLI.

      • I do not use RequireJS either. I use regular js objects and functions. The whole commonjs module deal is overhyped and it’s popular because nodejs is popular. ECMA Harmony will not use the commonjs approach for modules, so code based on them will eventually have to die. RequireJS, although better, will not stick either. But that is another discussion.

        The real question here is why do js2json and json2js, which imo can become popular libraries at least in the couchdb space, impose the use of commonjs modules. A restriction such as this (being it commonjs or requirejs or whatever) will hurt the project. I for one, cannot use it.

        Hail to the agnostic libraries.

      • Think about it this way, your libraries turn js code into json and back. That’s your pitch. That’s the value you are providing. Where in here, do we need to include commonjs or requirejs into the picture? That’s narrowing the use of the libraries. That’s unnecessary limiting.

        Please notice that all of my criticism comes from a deep and thankful appreciation of your work. Thanks for that.

Comments are closed.