{
  "author": {
    "name": "Ben Newman",
    "email": "bn@cs.stanford.edu"
  },
  "name": "commoner",
  "description": "Flexible tool for translating any dialect of JavaScript into Node-readable CommonJS modules",
  "keywords": [
    "modules",
    "require",
    "commonjs",
    "exports",
    "commoner",
    "browserify",
    "stitch"
  ],
  "version": "0.9.3",
  "license": "MIT",
  "homepage": "http://github.com/reactjs/commoner",
  "repository": {
    "type": "git",
    "url": "git://github.com/reactjs/commoner.git"
  },
  "main": "main.js",
  "bin": {
    "commonize": "./bin/commonize"
  },
  "scripts": {
    "test": "whiskey test/run.js"
  },
  "dependencies": {
    "q": "~1.0.1",
    "recast": "~0.5.12",
    "commander": "~2.2.0",
    "graceful-fs": "~2.0.3",
    "glob": "~3.2.9",
    "mkdirp": "~0.3.5",
    "private": "~0.1.2",
    "install": "~0.1.7",
    "iconv-lite": "~0.2.11",
    "whiskey": "0.6.x"
  },
  "optionalDependencies": {
    "whiskey": "0.6.x"
  },
  "engines": {
    "node": ">= 0.8"
  },
  "readme": "Commoner [![Build Status](https://travis-ci.org/reactjs/commoner.png?branch=master)](https://travis-ci.org/reactjs/commoner)\n---\n\nCommoner makes it easy to write scripts that flexibly and efficiently\ntranspile any dialect of JavaScript into a directory structure of\nNode-compatible CommonJS module files.\n\nThis task is made possible by\n\n  1. a declarative syntax for defining how module source code should be\n     found and processed,\n  2. the use of [promises](https://github.com/kriskowal/q) to manage an\n     asynchronous build pipeline, and\n  3. never rebuilding modules that have already been built.\n\nThe output files can be required seamlessly by Node, or served by any\nstatic file server, or bundled together using a tool such as\n[Browserify](https://github.com/substack/node-browserify),\n[WrapUp](https://github.com/kamicane/wrapup), or\n[Stitch](https://github.com/sstephenson/stitch) for delivery to a web\nbrowser.\n\nIf you pass the `--relativize` option, Commoner also takes care to rewrite\nall `require` calls to use [relative module\nidentifiers](http://wiki.commonjs.org/wiki/Modules/1.1#Module_Identifiers),\nso that the output files can be installed into any subdirectory of a\nlarger project, and external tools do not have to give special treatment\nto top-level modules (or even know which modules are top-level and which\nare nested).\n\nCommoner was derived from an earlier, more opinionated tool called\n[Brigade](https://github.com/benjamn/brigade) that provided additional\nsupport for packaging modules together into multiple non-overlapping\nbundles. Commoner grew out of the realization that many tools already\nexist for bundling CommonJS modules, but that fewer tools focus on getting\nto that point.\n\nInstallation\n---\n\nFrom NPM:\n\n    npm install commoner\n\nFrom GitHub:\n\n    cd path/to/node_modules\n    git clone git://github.com/reactjs/commoner.git\n    cd commoner\n    npm install .\n\nUsage\n---\n\nHere's the output of `bin/commonize --help`:\n```\nUsage: commonize [options] <source directory> <output directory> [<module ID> [<module ID> ...]]\n\nOptions:\n\n  -h, --help                               output usage information\n  -V, --version                            output the version number\n  -c, --config [file]                      JSON configuration file (no file means STDIN)\n  -w, --watch                              Continually rebuild\n  -x, --extension <js | coffee | ...>      File extension to assume when resolving module identifiers\n  --relativize                             Rewrite all module identifiers to be relative\n  --follow-requires                        Scan modules for required dependencies\n  --cache-dir <directory>                  Alternate directory to use for disk cache\n  --no-cache-dir                           Disable the disk cache\n  --source-charset <utf8 | win1252 | ...>  Charset of source (default: utf8)\n  --output-charset <utf8 | win1252 | ...>  Charset of output (default: utf8)\n```\n\nIn a single sentence: the `commonize` command finds modules with the given\nmodule identifiers in the source directory and places a processed copy of\neach module into the output directory, along with processed copies of all\nrequired modules.\n\nIf you do not provide any module identifiers, `commonize` will process all\nfiles that it can find under the source directory that have the preferred\nfile extension (`.js` by default). If your source files have a file\nextension other than `.js`, use the `-x` or `--extension` option to\nspecify it. For example, `--extension coffee` to find `.coffee` files.\n\nOutput\n---\n\nCommoner prints various status messages to `STDERR`, so that you can see\nwhat it's doing, or figure out why it's not doing what you thought it\nwould do.\n\nThe only information it prints to `STDOUT` is a JSON array of module\nidentifiers, which includes the identifiers passed on the command line and\nall their dependencies. This array contains no duplicates.\n\nInternally, each module that Commoner generates has a hash computed from\nthe module's identifier, source code, and processing steps. Since this\nhash can be computed before processing takes place, Commoner is able to\navoid processing a module if it has ever previously processed the same\nmodule in the same way.\n\nIf you dig into [the\ncode](https://github.com/reactjs/commoner/blob/5e7f65cab2/lib/context.js#L94),\nyou'll find that Commoner maintains a cache directory (by default,\n`~/.commoner/module-cache/`) containing files with names like\n`9ffc5c853aac07bc106da1dc1b2486903ca688bf.js`.  When Commoner is about to\nprocess a module, it checks its hash against the file names in this\ndirectory. If no match is found, processing procedes and the resulting\nfile is written to the cache directory with a new hash. If the appropriate\nhash file is already present in the cache directory, however, Commoner\nmerely creates a hard link between the hash file and a file with a more\nmeaningful name in the output directory.\n\nWhen you pass the `--watch` flag to `bin/commonize`, Commoner avoids\nexiting after the first build and instead watches for changes to\npreviously read files, printing a new JSON array of module identifiers to\n`STDOUT` each time rebuilding finishes. Thanks to the caching of processed\nmodules, the time taken to rebuild is roughly proportional to the number\nof modified files.\n\nCustomization\n---\n\nThe `bin/commonize` script is actually quite simple, and you can write\nsimilar scripts yourself. Let's have a look:\n```js\n#!/usr/bin/env node\n\nrequire(\"commoner\").resolve(function(id) {\n    var context = this;\n\n    return context.getProvidedP().then(function(idToPath) {\n        // If a module declares its own identifier using @providesModule\n        // then that identifier will be a key in the idToPath object.\n        if (idToPath.hasOwnProperty(id))\n            return context.readFileP(idToPath[id]);\n    });\n\n}, function(id) {\n    // Otherwise assume the identifier maps directly to a filesystem path.\n    // The readModuleP method simply appends the preferred file extension\n    // (usually .js) to the given module identifier and opens that file.\n    return this.readModuleP(id);\n});\n```\nThe scriptable interface of the `commoner` module abstracts away many of\nthe annoyances of writing a command-line script. In particular, you don't\nhave to do any parsing of command-line arguments, and you don't have to\nworry about installing any dependencies other than `commoner` in your\n`$NODE_PATH`.\n\nWhat you are responsible for, at a minimum, is telling Commoner how to\nfind the source of a module given a module identifier, and you do this by\npassing callback functions to `require(\"commoner\").resolve`. The script\nabove uses two strategies that will be tried in sequence: first, it calls\nthe helper function `this.getProvidedP` to retrieve an object mapping\nidentifiers to file paths (more about this below); and, if that doesn't\nwork, it falls back to interpreting the identifier as a path relative to\nthe source directory.\n\nNow, you might not care about `this.getProvidedP`. It's really just a\nproof of concept that Commoner can support modules that declare their own\nidentifiers using the `// @providesModule <identifier>` syntax, and I\nincluded it by default because it doesn't make a difference unless you\ndecide to use `@providesModule`. If you don't like it, you could write an\neven simpler script:\n```js\n#!/usr/bin/env node\n\nrequire(\"commoner\").resolve(function(id) {\n    return this.readModuleP(id);\n});\n```\nThe point is, it's entirely up to you to define how module identifiers are\ninterpreted. In fact, the source you return doesn't even have to be valid\nJavaScript. It could be [CoffeeScript](http://coffeescript.org/), or\n[LESS](http://lesscss.org/), or whatever language you prefer to write by\nhand. Commoner doesn't care what your source code looks like, because\nCommoner allows you to define arbitrary build steps to turn that source\ncode into plain old CommonJS.\n\nLet's consider the example of using LESS to write dynamic CSS\nmodules. First, let's apply what we already know to give special meaning\nto `.less` files:\n```js\n#!/usr/bin/env node\n\nrequire(\"commoner\").resolve(function(id) {\n    if (isLess(id))\n        return this.readFileP(id);\n}, function(id) {\n    return this.readModuleP(id);\n});\n\nfunction isLess(id) {\n    return /\\.less$/i.test(id);\n}\n```\nAll this really accomplishes is to avoid appending the `.js` file\nextension to identifiers that already have the `.less` extension.\n\nNow we need to make sure the contents of `.less` files somehow get\ntransformed into plain old CommonJS, and for that we need\n`require(\"commoner\").process`:\n```js\nrequire(\"commoner\").resolve(function(id) {\n    if (isLess(id))\n        return this.readFileP(id);\n}, function(id) {\n    return this.readModuleP(id);\n}).process(function(id, source) {\n    if (isLess(id))\n        return compileLessToJs(source);\n    return source;\n});\n```\nHow should `compileLessToJs` be implemented? At a high level, I propose\nthat we generate a CommonJS module that will append a new `<style>` tag to\nthe `<head>` the first time the module is required. This suggests to me\nthat we need to take the CSS generated by LESS and somehow embed it as a\nstring in a CommonJS module with a small amount of boilerplate JS.\n\nHere's a first attempt:\n```js\nfunction compileLessToJs(less) {\n    var css = require(\"less\").render(less);\n    return 'require(\"css\").add(' + JSON.stringify(css) + \");\";\n}\n```\nImplementing a `css` module with an appropriate `add` method is an\nexercise that I will leave to the reader (hint: you may find [this\nStackOverflow answer](http://stackoverflow.com/a/524721/128454) useful).\n\nThis almost works, but there's one problem: `require(\"less\").render` does\nnot actually return a string! For better or worse, it passes the compiled\nCSS to a callback function, which would make our task extremely painful\n*if Commoner were not deeply committed to supporting asynchronous\nprocessing*.\n\nCommoner uses promises for asynchronous control flow, so we need to return\na promise if we can't return a string immediately. The easiest way to make\na promise is to call `this.makePromise` in the following style:\n```js\n#!/usr/bin/env node\n\nrequire(\"commoner\").resolve(function(id) {\n    if (isLess(id))\n        return this.readFileP(id);\n}, function(id) {\n    return this.readModuleP(id);\n}).process(function(id, source) {\n    if (isLess(id)) {\n        return this.makePromise(function(nodeStyleCallback) {\n            compileLessToJs(source, nodeStyleCallback);\n        });\n    }\n    return source;\n});\n\nfunction compileLessToJs(less, callback) {\n    require(\"less\").render(less, function(err, css) {\n        callback(err, 'require(\"css\").add(' + JSON.stringify(css) + \");\")\n    });\n}\n```\nAnd we're done! This example was admittedly pretty involved, but if you\nfollowed it to the end you now have all the knowledge you need to write\nsource files like `sidebar.less` and require them from other modules by\ninvoking `require(\"sidebar.less\")`. (And, by the way, embedding dynamic\nCSS modules in your JavaScript turns out to be an excellent idea.)\n\nGenerating multiple files from one source module\n---\n\nCommoner is not limited to generating just one output file from each\nsource module. For example, if you want to follow best practices for\nproducing source maps, you probably want to create a `.map.json` file\ncorresponding to every `.js` file that you compile.\n\nRecall that normally your `.process` callback returns a string (or a\npromise for a string) whose contents will be written as a `.js` file in\nthe output directory. To write more than one file, just return an object\nwhose keys are the file extensions of the files you want to write, and\nwhose values are either strings or promises for strings representing the\ndesired contents of those files.\n\nHere's an example of generating two different files for every source\nmodule, one called `<id>.map.json` and the other called `<id>.js`:\n```js\nrequire(\"commoner\").resolve(function(id) {\n    return this.readModuleP(id);\n}).process(function(id, source) {\n    var result = compile(source);\n    return {\n        \".map.json\": JSON.stringify(result.sourceMap),\n        \".js\": [\n            result.code,\n            \"//# sourceMappingURL=\" + id + \".map.json\"\n        ].join(\"\\n\")\n    };\n});\n```\n\nNote that\n```js\nreturn {\n    \".js\": source\n};\n```\nwould be equivalent to\n```js\nreturn source;\n```\nso you only have to return an object when you want to generate multiple\nfiles. However, the `.js` key is mandatory when returning an object.\n\nFor your convenience, if you have a sequence of multiple processing\nfunctions, the values of the object returned from each step will be\nresolved before the object is passed along to the next processing\nfunction, so you can be sure all the values are strings (instead of\npromises) at the beginning of the next processing function.\n\nConfiguration\n---\n\nOf course, not all customization requires modifying code. Most of the\ntime, in fact, configuration has more to do with providing different\ndynamic values to the same code.\n\nFor that kind of configuration, you don't need to modify your Commoner\nscript at all, because Commoner scripts accept a flag called `--config`\nthat can either specify a JSON file or (if `--config` is given without a\nfile name) read a string of JSON from `STDIN`.\n\nExamples:\n\n    bin/commonize source/ output/ main --config release.json\n    bin/commonize source/ output/ main --config debug.json\n    echo '{\"debug\":false}' | bin/commonize source/ output/ main --config\n    echo '{\"debug\":true}' | bin/commonize source/ output/ main --config /dev/stdin\n\nThis configuration object is exposed to the `.resolve` and `.process`\ncallbacks as `this.config`. So, for example, if you wanted to implement\nminification as a processing step, you might do it like this:\n```js\nrequire(\"commoner\").resolve(function(id) {\n    return this.readModule(id);\n}).process(function(id, source) {\n    if (this.config.debug)\n        return source;\n    return minify(source);\n});\n```\nPerhaps the coolest thing about the configuration object is that Commoner\ngenerates a recursive hash of all its properties and their values which is\nthen incorporated into every module hash. This means that two modules with\nthe same identifier and identical source code and processing steps will\nhave distinct hashes if built using different configuration objects.\n\nCustom Options\n---\n\nYou can define custom options for your script by using the `option` function.\n\n```js\nrequire(\"commoner\").resolve(function(id) {\n    return this.readModule(id);\n}).option(\n    '--custom-option',\n    'This is a custom option.'\n).process(function(id, source) {\n    if (this.options.customOption) {\n        source = doCustomThing(source);\n    }\n    return source;\n});\n```\n\nFor more information of the options object available inside the `process` function see [Commander](https://github.com/visionmedia/commander.js).\n",
  "readmeFilename": "README.md",
  "bugs": {
    "url": "https://github.com/reactjs/commoner/issues"
  },
  "_id": "commoner@0.9.3",
  "_shasum": "ba8ed87ae4e9b6ed0a65a212f6795a54b178c272",
  "_from": "commoner@^0.9.2",
  "_resolved": "https://registry.npmjs.org/commoner/-/commoner-0.9.3.tgz"
}
