{"bin":{"component":"bin/component_proxy.js"},"dist":{"shasum":"143623a8cdfb5233b6e77814d8b8ce74f40c9297","tarball":"https://registry.npmjs.org/csi/-/csi-0.0.19.tgz","integrity":"sha512-32zpa43rHO3YFcZeXzPQUdRRqVHPqACOqQx/iVQjWmOq6hJIebRVK67uK1sz2zfL/8kET/YaQl6JIJoSzPbr0A==","signatures":[{"sig":"MEQCIF3GTOmHBt9/lvd1BzABYwl7azhgmnInez9h8Ced01FsAiBJA0mIVVKho6flM5/pPnxVtUc4nEJiWH0VvOy+T8t7yg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}]},"main":"server.js","name":"csi","author":{"name":"Aaron Stacy","email":"astacy@storediq.com"},"readme":"# `csi`\n\nclient side package tools for team players\n\n## go ahead, elevator pitch me.\n\n`csi` is a client side package manager for industrial strength software\nprojects.  it's built on [`require.js`][requirejs], and it allows you to write\nfull client-side components (`html`, `css`, and `javascript`) that can be\ninstalled anywhere within your app.  `csi` aims to be:\n\n - **backend agnostic** -- `csi` doesn't assume anything other than\n   [`npm`][npm] for dependency management.  you can use it with whatever\n   server-side framework you prefer.\n\n - **test-driven** -- `csi` provides built-in, easy to use testing with\n   [`qunit`][qunit], and it can be easily extended to use other frameworks like\n   [`mocha`][mocha].\n\n - **[`require.js`][requirejs] based** -- [`amd`][amd] is baked in with\n   `require.js`, and `csi` builds on that foundation to allow even more\n   modularity.\n\n - **whollistic** -- last time we checked, client-side web apps are composed of\n   not just javascript, but also `css` and markup.  `csi` helps you write\n   full components with `css` and `html` dependencies without having to worry\n   about where your assets will be stored.\n\n## let's get into some examples.\n\nlet's say you've got a module called `bird`, and its sole purpose is to [put a\nbird on it][bird_on_it].  it is so friggin useful that you want it in all the\napps that you make, even though some of your apps are 10 years old and they run\non perl-scripting-cgi-serving technology, and others are so hip that [you\nhaven't even heard of their framework yet][spire].  it goes something like\nthis:\n\n    var birdifyIt = function(node) {\n        $('<div>').addClass('with-a-bird-on-it').appendTo(node);\n    };\n\nand then you throw some css up somewhere:\n\n    .with-a-bird-on-it {\n      width: 640px\n      height: 480px;\n      background-image: url(bird.png);\n    }\n\nbut you want to leverage `amd` for code reuse, so you put it in a module:\n\n    define([\n        'jquery'\n    ], function($) {\n        return function(node) {\n            $('<div>').addClass('with-a-bird-on-it').appendTo(node);\n        };\n    });\n\nyou're even so savvy that you write a `css` plugin for `require.js` (maybe\nsomething like [this][requirejs_css]).  that way you can abstract the details\nof the code's styling from the caller:\n\n    define([\n        'jquery',\n        'css!bird.css'\n    ], function($) {\n        return function(node) {\n            $('<div>').addClass('with-a-bird-on-it').appendTo(node);\n        };\n    });\n\nyour code works, it's modular, your company is selling crap with birds on it\nleft and right, and your boss is so happy he comes over to your cubicle and\nhe's all like:\n\n> man that put-a-bird-on-it code you wrote is so sick, lets use it in our new\n> app, version 2.0!\n\n### the plot thickens.\n\nlike any good engineering organization, you guys completely re-architected\neverything in version 2.0, and now you're putting modules into their own little\nsubdirectories in order to help separate concerns.  you throw your bird module\ninto the `components/bird` directory, and BOOM, it stops working because the\npaths to `jquery.js`, `bird.css`, `bird.png` have changed.\n\nso now you've got to edit the bird code in order to put it in a new app.\nthat's not optimal, and since you didn't write any unit tests for it, you've\ngot that sinking \"i think i broke it when i touched it\" feeling.  \n\n### a simple `csi` module\n\nso what would it look like to have a fully modular way of doing this?  let's\nwrite it as a `csi` component.  we make a 'bird' repository with the following\ndirectory structure:\n\n    bird\n    |-- package.json\n    `-- src\n        |-- bird.css\n        |-- bird.js\n        `-- bird.png\n\n`bird.js` looks like:\n\n    define([\n        'component!vendor:jquery',\n        'css!./bird.css'\n    ], function() {\n        return function(node) {\n            $('<div>').addClass('with-a-bird-on-it').appendTo(node);\n        };\n    });\n\nlet's break down line 2 where we declare the `jquery.js` dependency:\n\n    'component!vendor:jquery'\n\n - `component!`: we're using the 'component' plugin\n\n - `vendor:`: and we want to declare a dependency from the `vendor` component\n\n - `jquery`: ...and that dependency is `jquery.js`.\n\nthe idea is that your plugin needs jquery, but it shouldn't have to know where\nit's located on the server.  so we add an extra level of indirection.  the\n`component` plugin looks up the path to the `vendor` component, and prepends\nthat to the target module `jquery.js` at page load (`csi` handles the details of\nthis lookup.  it's a bit out of scope for this tutorial though, so don't worry\nabout that right now).\n\nlet's also break down line 3 where we declare the `css` dependency:\n\n - `css!`: we're still using that slick 'css' plugin\n\n - `./bird.css`: and of course our filename, except now it's relative to the\n   bird component, so we won't need to update this if we put it in a different\n   project\n\nwe've also included an npm [package.json][package_json] file.  this is\nnecessary whether or not you plan on publishing to the npm registry because\nit's how we manage dependencies.  here's the contents:\n\n    {\n      \"author\": \"nature and stuff\",\n      \"name\": \"put-a-bird-on-it\",\n      \"description\": \"we put birds on things.\",\n      \"version\": \"0.0.0\",\n      \"engines\": {\n        \"node\": \"~0.6.11\"\n      },\n      \"dependencies\": {\n        \"siq-vendor-js\": \"0.0.x\",\n        \"csi\": \"0.0.x\"\n      },\n      \"component\": {\n        \"name\": \"bird\"\n      }\n    }\n\nthis is all pretty strait forward, but there are two important things:\n\n - **`csi` dependency**: declaring `csi` as a dependency gives us tools like the\n   `reqiure.js` path plugin and makes unit testing and code reuse a breeze.\n\n - **`component` property**: `csi` uses this to define the name of the\n   component.  the `component.name` property is required.\n\nbefore we get into how we include the bird component, let's write a quick qunit\ntest to cover ourselves in future refactorings:\n\n    define([\n        'component!vendor:jquery'\n        'component!bird:bird'\n    ], function($, birdifyIt) {\n\n        test('put an effin bird on it', function() {\n            birdifyIt($('body'));\n            equal($('body').children().last()[0].className, 'with-a-bird-on-it');\n        });\n\n        start();\n    });\n\nrunning the test is easy:\n\n    $ npm install\n    $ node_modules/.bin/component test\n\nthis will start up a server for you and list out URL's you can visit to run\ntests.  open up [http://localhost:1335/components/bird/test][test] in your\nbrowser.\n\n### including components in an app\n\nnow back to your app version 2.0.  you'll have a directory structure like this:\n\n    app_v2\n    |-- package.json\n    `-- static\n        |-- bluejay.js\n        `-- index.js\n\nyour sweet new `bluejay` module extends the functionality of `birdifyIt`:\n\n    define([\n        'component!bird:bird'\n    ], function(birdifyIt) {\n        return function(node) {\n            var childNodes;\n            birdifyIt(node);\n            childNodes = node.childNodes;\n            childNodes[childNodes.length-1].style.backgroundColor = 'blue';\n        };\n    });\n\n**#protip**: you can use the shorthand `path!bird` instead of\n`path!bird:bird`, and `csi` is smart enough to load the default module\n\nand then you can add an entry point at `static/index.js`\n\n    define([\n        'bluejay'\n    ], function(bluejay) {\n        var body = document.getElementsByTagName('body')[0];\n        bluejay(body);\n    });\n\nand your `package.json` will be:\n\n    {\n      \"name\": \"app_v2\",\n      \"description\": \"the new hotness in aviary appification\",\n      \"version\": \"0.0.0\",\n      \"engines\": {\n        \"node\": \"~0.6.11\"\n      },\n      \"dependencies\": {\n        \"siq-vendor-js\": \"0.0.x\",\n        \"csi\": \"0.0.x\",\n        \"put-a-bird-on-it\": \"git://github.com/aaronj1335/put-a-bird-on-it.git\"\n      }\n    }\n\nthanks to npm's [flexible dependency specification][json_deps], we can just use\na `git` url, but you could of course use the npm registry or the location of a\ntarball.\n\nrunning tests is still easy:\n\n    $ npm install\n    $ node_modules/.bin/component test\n\nsince we defined the entry point in `static/index.js`, we can open\n[http://localhost:1335/index][index].  `csi` is smart enough to figure out that\nthis is not a test module (since it doesn't have 'test' in the filename), so\nyour page loads as without all the `qunit` stuff.\n\n## bada bing\n\nand there you have it, modular client-side development.  there are quite a few\ndetails that we glossed over, such as the mechanics of installing components\n(hint: they go in a directory called `components`), and the fact that [`csi`\nmay re-write `url()` paths in `css`][css_url_rewrite] files, but hopefully this\nwas an instructive tutorial.  [feel free to tinker/fork/pr][example].  the best\nway to get a feel for `csi` would probably be to check out working examples:\n\n - [`gloss`][gloss]: a UI framework.  this makes heavy use of `csi`.  it also\n   includes an example of client-side templating with [John Resig's\n   micro-templating][microtemplates].  it utilizes the following dependencies:\n\n     - [`siq-vendor-js`][vendorjs]: third-party stuff like jquery and\n       underscore\n\n     - [`bedrockjs`][bedrock]: our class and (non-DOM) event implementation\n\n     - [`mesh`][mesh]: our integrated REST framework\n\n\n[bird_on_it]: http://www.youtube.com/watch?v=0XM3vWJmpfo\n[spire]: https://github.com/siq/spire\n[gloss]: https://github.com/siq/gloss\n[vendorjs]: https://github.com/siq/siq-vendor-js\n[requirejs]: http://requirejs.org/\n[package_json]: http://npmjs.org/doc/json.html\n[json_deps]: http://npmjs.org/doc/json.html#dependencies\n[css_url_rewrite]: https://github.com/siq/csi/blob/master/lib/css_requirejs_plugin.js#L139\n[test]: http://localhost:1335/components/bird/test\n[index]: http://localhost:1335/index\n[bedrock]: https://github.com/siq/B\n[mesh]: https://github.com/siq/mesh\n[microtemplates]: http://ejohn.org/blog/javascript-micro-templating/\n[npm]: http://npmjs.org/\n[qunit]: http://docs.jquery.com/QUnit\n[mocha]: http://visionmedia.github.com/mocha/\n[amd]: https://github.com/amdjs/amdjs-api/wiki/AMD\n[requirejs_css]: https://github.com/VIISON/RequireCSS\n[example]: https://github.com/aaronj1335/bird-app-v2\n","engines":{"node":"~0.6.11"},"scripts":{"test":"node_modules/.bin/coffee component.coffee -l test","start":"node server.js","install":"node bin/build.js"},"component":{"name":"csi","testDirectory":"test"},"repository":{"url":""},"description":"siq client-side infrastructure","directories":{},"maintainers":[{"name":"aaronj1335","email":"aaron.r.stacy@gmail.com"}],"dependencies":{"t":"0.4.x","async":"0.1.x","qunit":"0.5.x","colors":"0.6.x","wrench":"1.3.x","js-yaml":"0.3.x","optimist":"0.3.x","underscore":"1.3.x","docco-husky":"0.3.x","node.extend":"=1.0.0","coffee-script":"1.2.x"},"devDependencies":{},"optionalDependencies":{"docco-husky":"0.3.x"},"_id":"csi@0.0.19","version":"0.0.19"}