├── .gitignore ├── creating-components ├── standalone-umd-builds.md ├── best-practices.md ├── debugging.md ├── publishing.md └── locals.md ├── creating-apps-with-components ├── entry-points.md ├── css-ordering.md ├── best-practices.md └── modules.md ├── component ├── examples.md ├── troubleshooting.md ├── api.md ├── repositories.md ├── vs.md ├── getting-started.md └── faq.md ├── Readme.md └── changelogs └── 1.0.0.md /.gitignore: -------------------------------------------------------------------------------- 1 | !*.md -------------------------------------------------------------------------------- /creating-components/standalone-umd-builds.md: -------------------------------------------------------------------------------- 1 | 2 | You may create a standalone build, including all dependencies, using the `component build --standalone ` command. This will create a [umd](https://github.com/umdjs/umd)-wrapped version of your build. 3 | 4 | Services may automatically build UMD-wrapped standalone builds of components. However, it probably uses the component's `name` property as the global name by default. If you would like to use a custom name, for example, a capitalized name, then set `.standalone` as your preferred global name. 5 | 6 | ```json 7 | { 8 | "name": "emitter", 9 | "standalone": "Emitter" 10 | } 11 | ``` 12 | 13 | Note that this `.standalone` property is not in the `component.json` specification and is only relevant to automated builds. It does nothing with your local components. 14 | 15 | 16 | Evaluation priority: 17 | 18 | 1. CLI parameter passed after `--standalone` or `--umd` 19 | 2. `.standalone` property in the root component 20 | 3. `.name` property in the root component 21 | -------------------------------------------------------------------------------- /creating-apps-with-components/entry-points.md: -------------------------------------------------------------------------------- 1 | Every component, module, and app needs an entry point. In general, this is the `index.js` file or whatever is listed as `main`. However, you'll notice that many examples have `component.json`s that look like this: 2 | 3 | ```json 4 | { 5 | "name": "app", 6 | "locals": ["boot"], 7 | "paths": ["lib"] 8 | } 9 | ``` 10 | 11 | That is, there's no `.scripts`, and a single `boot` local. What this means is that that the entry point is deferred to `boot`, so the build will automatically `require('boot')` instead of `require('app')`. The main reason for doing so is to avoid having any files at the top of your directory, which makes it cleaner. 12 | 13 | It's important to either have an JS file as your entry point or a single local. If there's more than one local, Component doesn't know what to do. Is each `local` an entry point? Are they different bundles? Etc. Having multiple locals is more complex and much more opinionated. Thus, if you have multiple locals, you'll get a build error with `component build`. 14 | 15 | If you want multiple bundles or multiple entry points for your app, look into [component-bundler](https://github.com/component/bundler.js) as to how to do so with the JS API. 16 | -------------------------------------------------------------------------------- /creating-components/best-practices.md: -------------------------------------------------------------------------------- 1 | 2 | To do: merge https://github.com/component/component/wiki/Building-better-components 3 | 4 | ## Use wide semver ranges 5 | 6 | It's more important in the browser than the server to make sure you don't have duplicate components. You don't want to have multiple versions of a component in your final build as that is unnecessary bloat. 7 | 8 | To safeguard against this, use wide semver ranges in your public components, and let apps pin dependencies themselves. Use `^` for dependencies `> 1.0.0`, and `~` otherwise. 9 | 10 | ## Write new components as ES6 modules 11 | 12 | Unlike CommonJS or AMD, ES6 module loading is an actual standard. 13 | Begin writing your components as ES6 modules as it will allow your module to be used in more package managers and build systems than just Component and Browserify. 14 | 15 | ## Publishing to `npm` 16 | 17 | If you've chosen a name taken in `npm`'s registry, 18 | publish the component as `-`. 19 | This allows people to use `require(-)` in either Component, Browserify, or Node without any hacks. 20 | 21 | ## Only use lowercased letters in files and component names 22 | 23 | Some file systems are case sensitive, others are not. 24 | Let's keep components as compatible as possible! 25 | -------------------------------------------------------------------------------- /creating-components/debugging.md: -------------------------------------------------------------------------------- 1 | # Debugging 2 | 3 | If you run `component build --dev` your build output become almost commented out and at the end you see a line which looks like so: 4 | 5 | ``` 6 | //# sourceURL=file.js" 7 | ``` 8 | 9 | Actually this works in Chrome without problems, but Firefox doesn't support it and Safari show you the reference files but the breakpoints don't work. 10 | 11 | # Aliases 12 | 13 | Furthermore you have aliases for the registered modules with the `--dev` option. With the aliases you can open the browser console and require aliases instead of the full module name. 14 | 15 | If a local components name is unique in your app, you can just require the name. Otherwise you need to use a canonical path, relative to the root component, starting with `./`, for instance you have defined to paths in your root component: `['view', 'model']` and in each of them a `user` component. Then you need to `require('./view/user')`. 16 | 17 | If you want to require another file than defined in the `.main` field of your component, you also need a canonical path. 18 | 19 | Ditto for remote componets, for instance you can `require('emitter')` if you have only one component with the name. If there is a name clash, you can type `require('component~emitter')`, joining username and repository with `~`. The canonical paths contains the version as well, like: `component~emitter@1.0.0` -------------------------------------------------------------------------------- /creating-components/publishing.md: -------------------------------------------------------------------------------- 1 | 2 | ## Pushing Git Tags 3 | 4 | Unlike Bower or NPM, Component does not have its own registry. 5 | Instead, you simply `git push` semantically versioned tags. 6 | For example, to publish version `1.0.0` of a component: 7 | 8 | ```js 9 | git commit -a -m "1.0.0" 10 | git push origin master 1.0.0 11 | ``` 12 | 13 | ### Crawling 14 | 15 | Instead of publishing, Component has a [crawler](https://github.com/component/crawler.js) that crawls all a GitHub user/organization's repositories. 16 | All crawled repositories will be discoverable through http://component.io as well as `component search`. 17 | 18 | However, there are rules to being crawled: 19 | 20 | - A `component.json` must exist in the default branch 21 | - The `component.json` must not have `private: true` 22 | - GitHub issues __must__ be enabled 23 | - The repository must not be bare or empty 24 | 25 | ## Best Practices 26 | 27 | ### Stick to `master` 28 | 29 | In general, you should stick with `master` as your default branch. 30 | By default, Component will check `master` for a `component.json` to check whether the repository is a "component". 31 | Supporting default branches other than `master` would require additional HTTP requests as well as use GitHub API requests. 32 | 33 | ### Don't prefix `v` to the version 34 | 35 | This isn't a big deal, but you should generally not prefix versions with a `v`. 36 | Component will handle both cases, but doing so requires an extra HTTP request. 37 | -------------------------------------------------------------------------------- /component/examples.md: -------------------------------------------------------------------------------- 1 | 2 | Boilerplates: 3 | 4 | - [component-boilerplate-express](https://github.com/component/boilerplate-express) 5 | - [component-boilerplate-koa](https://github.com/component/boilerplate-koa) 6 | - [component-koa-et-al-boilerplate](https://github.com/sunewt/component-koa-et-al-boilerplate) 7 | 8 | Examples: 9 | 10 | - Different examples how to use component, step by step [c8-experiments](https://github.com/timaschew/c8-experiments) 11 | - Example using [script tags](https://github.com/component/script-tag-example) for integrating component with existing non-commonjs applications or frameworks 12 | - [kewah/component-example](https://github.com/kewah/component-example) - simple app example (router + transition between pages) 13 | - [Todo list](https://github.com/component/todo) example comprised of private and public components 14 | 15 | Apps: 16 | 17 | - [component.github.io](https://github.com/component/component.github.io) website to searching components 18 | - [NoFlo](http://noflojs.org/) flow-based programming environment 19 | [code42day/liftie](https://github.com/code42day/liftie) ([live](http://liftie.info)) - simple, easy to read, fast ski resort lift status 20 | 21 | Libraries: 22 | 23 | - [segmentio/hn-button.com](https://github.com/segmentio/hn-button.com) ([live](http://hn-button.com)) - the Hacker News button 24 | - [segmentio/analytics.js](https://github.com/segmentio/analytics.js) 25 | 26 | Companies using Component: 27 | 28 | - [segmentio](https://segment.io) 29 | - [Actano GmbH](http://rplan.net) 30 | -------------------------------------------------------------------------------- /creating-components/locals.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | Your application is usually structured into multiple components. 4 | You have either remote or local components. Local components can be listed in each __component.json__ like so: 5 | 6 | ```js 7 | "locals": ["qux", "baz"] 8 | ``` 9 | 10 | __Note:__ All components need to be lower case! Component will lowercase all you `require()` calls due to keep compatibility between case sensitive and case insensitive file systems. 11 | 12 | # Nested Structure 13 | Your root component defines a `.paths` array where component try to lookup your local components. So your components don't need to know where other local components exist. 14 | 15 | Local components don't need a `.name` field, they just use its folder name. You can also provide a subdirectories as a local component to use kind of namespacing: 16 | 17 | ```js 18 | "locals": ["foo/bar", "/qux/bar"] 19 | ``` 20 | 21 | Another way to structure your component is to use multiple `.paths` values in your root component. See [Components Structure](../creating-apps-with-components/best-practices.md#Components structure). 22 | 23 | # Require Locals 24 | 25 | Local components can be required with its name like `require('qux')`. 26 | The result is the exported module of the main file, which you define in your component.json as `.main`. 27 | 28 | You can also require the other scripts of a foreign component just by writing: `require('qux/script')`. See also [Aliases](debugging.md#Aliases). 29 | 30 | [component specifications](https://github.com/componentjs/spec/blob/master/component.json/specifications.md#locals) 31 | -------------------------------------------------------------------------------- /creating-apps-with-components/css-ordering.md: -------------------------------------------------------------------------------- 1 | 2 | Traditionally, you would manually list all your `CSS` files into a concatenation step like so: 3 | 4 | ```css 5 | @import "normalize.css" 6 | @import "reset.css" 7 | @import "type.css" 8 | @import "layout.css" 9 | @import "buttons.css" /* depends on type.css */ 10 | @import "asides.css" 11 | @import "aside-buttons.css" /* depends on buttons.css and asides.css*/ 12 | ``` 13 | 14 | However, this is unmanageable with a lot of CSS files as you are prone to ordering mistakes and duplicates. It is also difficult to understand which CSS files are dependent on other CSS files, as demonstrated by the comments. 15 | 16 | Thus, with Component, you can split each CSS file into its own separate component, perhaps with relevant JS files, like this: 17 | 18 | `aside-buttons`: 19 | 20 | ```json 21 | { 22 | "locals": [ 23 | "buttons", 24 | "asides" 25 | ], 26 | "scripts": ["*.js"], 27 | "styles": ["*.css"] 28 | } 29 | ``` 30 | 31 | `locals` means local dependencies. By listing `buttons` and `asides` as local dependencies, Component will guarantee that `buttons` and `asides` are placed before `aside-buttons` in the CSS build. 32 | 33 | Then in your `boot` component, you simply list all the components, placing dependencies you __need__ at the top first: 34 | 35 | ```json 36 | { 37 | "dependencies": { 38 | "necolas/normalize.css": "*" 39 | }, 40 | "locals": [ 41 | "reset", 42 | "type", 43 | "layout", 44 | "buttons", 45 | "asides", 46 | "aside-buttons" 47 | ] 48 | } 49 | ``` 50 | 51 | Component will now handle the CSS ordering itself, so you don't have to worry about whether CSS files are included twice or are in the wrong or right order. The only downside to this is that it is a little verbose. 52 | -------------------------------------------------------------------------------- /creating-apps-with-components/best-practices.md: -------------------------------------------------------------------------------- 1 | 2 | # Components structure 3 | 4 | Try to keep all your components in a single path unless the number of components you use in that single path is unmanageable. 5 | 6 | If you do start using multiple paths, you should not use `locals` not within a path above the current path. For example, suppose you have the following structure: 7 | 8 | ```js 9 | view/ 10 | user/component.json 11 | page/component.json 12 | model/ 13 | user/component.json 14 | page/component.json 15 | ``` 16 | 17 | From `view/user`, you should NOT do `require('user')`. You should prefix every component in `model/` with `model-` and do `require('model-user')` or use [Nested Structure](../creating-components/locals.md#Nested Structure). 18 | 19 | # Pin dependencies 20 | 21 | Dependency updates may break your app. As a safeguard against this, you should pin your dependencies with `component pin`. Then, once in a while, run `component-update` and test your app to make sure it works with the newest versions of dependencies. 22 | 23 | ## Avoid the file builder in development 24 | 25 | Instead, you only need to do `component build styles scripts`. 26 | The reason is that you can simply serve the `build/` folder, `components/` folder, and the root folder in development, 27 | and all the files will automatically be served in your app. 28 | This avoids any unnecessary re-symlinking or re-copying during development, 29 | as well as automatic `mtime` checking done by your file server. 30 | 31 | In fact, you can avoid running `component build` at all during development. You might be interested in these two middleware and boilerplates: 32 | 33 | Boilerplates: 34 | 35 | - https://github.com/component/boilerplate-koa 36 | - https://github.com/component/boilerplate-express 37 | 38 | Middleware: 39 | 40 | - https://github.com/component/koa.js 41 | - https://github.com/component/middleware.js 42 | 43 | ## Avoid using files in your app 44 | 45 | Instead, move any static files (not included in your `.js` or `.css` files) to separate repositories. 46 | The main reason is that if you serve static assets with your app, 47 | they are not versioned by component. 48 | If instead you move them to a separate repository and add them as dependencies, 49 | they will be versioned by the builder. 50 | -------------------------------------------------------------------------------- /creating-apps-with-components/modules.md: -------------------------------------------------------------------------------- 1 | # Modules 2 | 3 | The Philosophy of Component is to create small self contained modules that do one thing very well. In the land of Javascript there is no such thing as a module system yet. Because of that, Component has it's own module system based on the [commonjs]() spec. If you have programmed with node before this should sound very familiar. If you haven't, check out this great [Introduction]() where you learn all about it. As of ECMAScript 6, a module system is baked right into the language. Event though commonjs modules are great we want to move forward and support the official module spec. The Browser support for ES6 Modules isn't wide enough to use it in production but Component has a solution to use ES6 modules Today! Let's take a look how we do it: 4 | 5 | Let's import a module with ES6: 6 | 7 | ```js 8 | import store from 'dex'; 9 | ``` 10 | 11 | This simply gets rewritten into standard commonjs `require()`s 12 | 13 | ```js 14 | var store = require('dex'); 15 | ``` 16 | 17 | As the ES6 spec finalizes we can remove this additional build step but it'll be a great solution before it lands in all major browser as it will allow users more time to adapt their components to the native module system. 18 | 19 | ## Compatibility with existing components 20 | 21 | ### commonjs ► ES6 22 | Components that are based on commonjs can be imported via ES6 modules. 23 | 24 | _a.js:_ 25 | 26 | ```js 27 | module.exports = function (a, b) { return a + b } 28 | ``` 29 | 30 | _b.js:_ 31 | 32 | ```js 33 | import add from './a.js' 34 | 35 | add(3, 5) 36 | // => 8 37 | ``` 38 | 39 | ### ES6 ► commonjs 40 | Components that are based on ES6 modules can be imported via commonjs. 41 | 42 | _a.js:_ 43 | 44 | ```js 45 | export default function (a, b) { return a + b } 46 | ``` 47 | 48 | _b.js:_ 49 | 50 | ```js 51 | var add = require('./a.js') 52 | 53 | add(3, 5) 54 | // => 8 55 | ``` 56 | 57 | ## How to use ES6 modules 58 | 59 | ### Import... 60 | 61 | ... a method: 62 | 63 | ```js 64 | import { set, get } from 'map' 65 | 66 | // => 67 | // var set = require('map').set 68 | // var get = require('map').get 69 | ``` 70 | 71 | ... a default method: 72 | 73 | ```js 74 | import foo from 'foo' 75 | 76 | // => var foo = require('foo') 77 | ``` 78 | 79 | ... all methods: 80 | 81 | ```js 82 | import * from 'map' 83 | 84 | // => 85 | // var a = require('map').a 86 | // var b = require('map').b 87 | // ... 88 | ``` 89 | 90 | ... local files: 91 | 92 | ```js 93 | import local from './local' 94 | 95 | // => var local = require('./local') 96 | ``` 97 | 98 | ### Export... 99 | 100 | ... a method: 101 | 102 | ```js 103 | export function fn () {} 104 | 105 | // => exports.fn = function () {} 106 | ``` 107 | 108 | ... a default method: 109 | 110 | ```js 111 | export default function fn () {} 112 | 113 | // => module.exports = function fn () {} 114 | ``` 115 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # THIS PROJECT IS DEPRECATED 2 | Component is __deprecated__, see [componentjs/component](https://github.com/componentjs/component/blob/master/Readme.md) 3 | 4 | # Component Guide 5 | 6 | A public wiki guide for [component][component]. 7 | Have questions about component? Open up an issue. 8 | Created a screencast or blog post about component? Link it here. 9 | Feel free to open a PRs with edits! Please be concise! 10 | 11 | ## Changelogs 12 | 13 | - [v1.0.0](changelogs/1.0.0.md) 14 | 15 | You can always view the boring [history.md](https://github.com/componentjs/component/blob/master/History.md). 16 | 17 | ## Community 18 | 19 | - [Mailing List](https://groups.google.com/group/componentjs) 20 | - [Google+ Community](https://plus.google.com/u/0/communities/109771441994395167277) 21 | - join `#components` on freenode 22 | - follow [@component_js](http://twitter.com/component_js) on twitter 23 | 24 | 25 | ## Table of Contents 26 | 27 | `component(1)`: 28 | 29 | - [Getting Started](component/getting-started.md) 30 | - [Examples](component/examples.md) 31 | - [Component vs.](component/vs.md) - Component use-cases and comparison with other frontend solutions 32 | - [FAQ](component/faq.md) 33 | - [Repositories](component/repositories.md) - internal components of `component(1)` and different plugins 34 | - [Troubleshooting](component/troubleshooting.md) 35 | 36 | Guide to Creating Components: 37 | 38 | - [Local Components](creating-components/locals.md) 39 | - [Debugging Components](creating-components/debugging.md) 40 | - [Publishing Components](creating-components/publishing.md) 41 | - [Standalone UMD Builds](creating-components/standalone-umd-builds.md) 42 | - [Best Practices](creating-components/best-practices.md) 43 | 44 | Guide to Creating Apps with Components: 45 | 46 | - [Entry Points](creating-apps-with-components/entry-points.md) 47 | - [CSS Ordering](creating-apps-with-components/css-ordering.md) 48 | - [Best Practices](creating-apps-with-components/best-practices.md) 49 | 50 | 51 | ## Screencasts 52 | 53 | - [Creating web components](https://vimeo.com/53730178) 54 | - [App integration introduction](https://vimeo.com/48054442) 55 | - [Introduction to Component](https://vimeo.com/86336598) 56 | - [Component Part 2: Making Your Own](https://vimeo.com/86339228) 57 | 58 | ## Articles 59 | 60 | - building a [date picker component](http://tjholowaychuk.tumblr.com/post/37832588021/building-a-date-picker-component) 61 | - original [component blog post](http://tjholowaychuk.tumblr.com/post/27984551477/components) 62 | - [build a Web app](http://blog.kewah.com/2014/build-a-web-app-with-component/) with component 63 | - [Introduction to Component](http://smalljs.org/package-managers/component-part-1/) 64 | - [Component Part 2: Making Your Own](http://smalljs.org/package-managers/component-part-2/) 65 | 66 | ## Official Links 67 | 68 | - [Component(1)](https://github.com/componentjs/component) 69 | - [Guide](https://github.com/componentjs/guide) 70 | - [Specifications](https://github.com/componentjs/spec) 71 | - [Component.IO](https://github.com/componentjs/component.io) 72 | 73 | [component]: https://github.com/componentjs/component 74 | -------------------------------------------------------------------------------- /component/troubleshooting.md: -------------------------------------------------------------------------------- 1 | If you're running into issues with Component, the first step you should do is run `component validate`. This will validate your `component.json` files and tell you if there are any major issues with your `component.json`. 2 | 3 | The next step is to use the `DEBUG` environmental variable. [Read more about how DEBUG works](https://github.com/visionmedia/debug). For a quick debug statement, run your command prefixed with `DEBUG=component*`. For example, this debugs a `component update` command: 4 | 5 | ```bash 6 | $ DEBUG=component* component update 7 | component-resolver remote not set - defaulting to ["github"] +0ms 8 | component-resolver:locals resolving local at "/Users/jong/Workspace/test" +0ms 9 | component-resolver resolving "asdf" +11ms 10 | component-resolver:locals resolving "asdf"'s local dependency "test". +5ms 11 | component-resolver:locals looking up "asdf"'s local dependency "test" at "/Users/jong/Workspace/test/lib/test". +0ms 12 | component-resolver remaining dependencies: 0 +1ms 13 | component-resolver remaining semver: 0 +0ms 14 | component-resolver:locals resolving local at "/Users/jong/Workspace/test/lib/test" +1ms 15 | component-resolver resolving "test" +2ms 16 | component-resolver remaining dependencies: 0 +0ms 17 | component-resolver remaining semver: 0 +0ms 18 | component-resolver:locals resolved local "asdf" +1ms 19 | component-resolver finished resolving locals +1ms 20 | component-resolver finished resolving dependencies (1) +0ms 21 | component-resolver finished installing dependencies +0ms 22 | update : updating asdf's pinned dependencies 23 | update : updated asdf's ranged dependencies in 743ms 24 | ``` 25 | 26 | You may also be interested in `DEBUG=remotes*` for when dependencies don't install, specifically those `error : Error: no remote found for dependency "es-shims/es5-shim@v2.3.0".` messages. Some common causes for this error are: 27 | 28 | - The repository does not exist. 29 | - The repository was deleted or has moved to a different location. 30 | - The version specified does not have a `component.json`, but `master` does. In this case, specify `master` as the version ask the maintainer to create a new release with a `component.json`. 31 | 32 | Here's an example on debugging: 33 | 34 | ```bash 35 | $ DEBUG=remotes* component install es-shims/es5-shim@v2.3.0 36 | remotes:local checking local components at /Users/jong/Workspace/test/components +0ms 37 | remotes:local resolving local remote +11ms 38 | remotes:local checking folder: /Users/jong/Workspace/test/components/es-shims/es5-shim +1ms 39 | remotes:github GET "https://raw.githubusercontent.com/es-shims/es5-shim/v2.3.0/component.json" +0ms 40 | remotes:github GET "https://raw.github.com/es-shims/es5-shim/v2.3.0/component.json" +352ms 41 | remotes:github GET "https://raw.githubusercontent.com/es-shims/es5-shim/v2.3.0/component.json" +284ms 42 | remotes:github GET "https://raw.github.com/es-shims/es5-shim/v2.3.0/component.json" +124ms 43 | 44 | error : Error: no remote found for dependency "es-shims/es5-shim@v2.3.0". 45 | ``` 46 | 47 | This shows you which URLs were tried, and since no remote was found, all of these URLs 404'd. 48 | 49 | -------------------------------------------------------------------------------- /component/api.md: -------------------------------------------------------------------------------- 1 | 2 | These are docs for specific `component(1)` commands. 3 | 4 | ## build 5 | 6 | Builds your component into `.js` and `.css` bundles and installs any necessary dependencies in the process. 7 | 8 | You __should__ use the `--watch` option, especially when building components, as it will make subsequent builds very fast as file transformations are cached in memory. When using `--watch`, you can type `r`, `s`, and `c` to `build`, `build scripts`, and `build styles`, respectively. 9 | 10 | Livereload users, you could use the `--reload` option, this is simply `--watch` with a livereload server. Don't forget to enable your favorite [livereload browser extension](http://feedback.livereload.com/knowledgebase/articles/86242-how-do-i-install-and-use-the-browser-extensions-) or just include the [livereload client script](http://feedback.livereload.com/knowledgebase/articles/86180-how-do-i-add-the-script-tag-manually). 11 | 12 | An alternative to the `--watch` option is using [middleware](repositories.md#middleware), more suited for apps. 13 | 14 | The `--dev` option does the following: 15 | 16 | - Installs and includes development dependencies in the build. 17 | - Use [source URLs](https://developers.google.com/chrome-developer-tools/docs/javascript-debugging) for better debugging in Chrome. 18 | - Create aliases so you can `require()` without worrying about versions. 19 | 20 | ## crawl 21 | 22 | This pings the [crawler](https://github.com/component/crawler.js) to crawl a specific user or organization. Note that executing `component crawl` only adds this specific user/organization to the crawl queue. 23 | 24 | You can then search for these components using `component search`. 25 | 26 | ## duplicates 27 | 28 | To minimize the bundle size, this will check for any dependencies that have multiple versions installed, and list which components use each version. 29 | 30 | ## install 31 | 32 | Installs all the components to the `components/` folder. This step is generally unnecessary as the `component build` command already handles it. 33 | 34 | ## link 35 | 36 | This will link a component on your hard drive to the current `components/` folder, treating it as a versioned dependency. There are, however, rules to linking: 37 | 38 | - The component cannot be inside the current folder, i.e. the path must start with `..`. 39 | - Do not include `component.json` in the path - link the folder. 40 | - The component must have a `.repository` field, though you can override this field with `--repository`. 41 | - The component must have a `.version` field. 42 | 43 | ## ls 44 | 45 | Show the dependency tree of the current component. 46 | 47 | ## outdated 48 | 49 | Checks for any outdated __pinned__ dependencies. This is more suited for apps. 50 | 51 | ## pin 52 | 53 | Pin any semver-ranged dependencies to the highest, installed version. This is more suited for apps as public components __should__ use semver ranges.. 54 | 55 | ## search 56 | 57 | Search [crawled](http://github.com/component/crawler.js) components. 58 | 59 | ## update 60 | 61 | Update any outdated __pinned__ dependencies. This is more suited for apps. 62 | 63 | ## validate 64 | 65 | Checks all your `component.json`s for [specification compliance](https://github.com/component/spec/blob/master/component.json/specifications.md). 66 | -------------------------------------------------------------------------------- /component/repositories.md: -------------------------------------------------------------------------------- 1 | 2 | Component(1) is split into many repositories. This makes maintenance much easier as most have their own test suites. All of these libraries are in the [components organization](https://github.com/component) and have a `.js` suffix. 3 | 4 | Note that these are only the official libraries. 5 | 6 | ### The major libraries you may be interested in are: 7 | 8 | - [component-remotes](https://github.com/component/remotes.js) - unify remote endpoint APIs 9 | - [component-resolver](https://github.com/component/resolver.js) - resolve the dependency tree with optional installing 10 | - [component-builder](https://github.com/component/builder2.js) - the build system 11 | 12 | ### Libraries synonymous to Component(1) commands: 13 | 14 | - [component-build](https://github.com/component/build.js) 15 | - [component-create](https://github.com/component/create.js) 16 | - [component-ls](https://github.com/component/ls.js) 17 | - [component-outdated](https://github.com/component/outdated.js) 18 | - [component-pin](https://github.com/component/pin.js) 19 | - [component-update](https://github.com/component/update.js) 20 | - [component-validator](https://github.com/component/validator.js) 21 | - [component-watcher](https://github.com/component/watcher.js) 22 | 23 | ### component dependencies 24 | 25 | ``` 26 | component 27 | ├─┬ component-build 28 | │ ├── builder-autoprefixer 29 | │ └─┬ component-builder 30 | │ ├── component-manifest 31 | │ └── component-require2 32 | ├── component-consoler 33 | ├── component-flatten 34 | ├── component-ls 35 | ├── component-outdated2 36 | ├── component-pin 37 | ├─┬ component-resolver 38 | │ ├── component-consoler 39 | │ ├── component-downloader 40 | │ └── component-validator 41 | ├── component-search2 42 | ├── component-updater 43 | ├── component-watcher 44 | └─┬ component-remotes 45 | └─┬ component-validator 46 | └── component-consoler 47 | ``` 48 | 49 | 50 | ### Other JS libraries: 51 | 52 | - [component-bundler](https://github.com/component/bundler.js) 53 | - [component-consoler](https://github.com/component/console.js) 54 | - [component-crawler](https://github.com/component/crawler.js) 55 | - [component-downloader](https://github.com/component/downloader.js) 56 | - [component-flatten](https://github.com/component/flatten.js) 57 | - [component-manifest](https://github.com/component/manifest.js) 58 | - [component-require2](https://github.com/component/require2) - Component's `require()` implementation 59 | 60 | ### Builder Plugins: 61 | 62 | - [builder-autoprefixer](https://github.com/component/builder-autoprefixer) 63 | - [builder-coffee-script](https://github.com/component/builder-coffee) 64 | - [builder-es6-module-to-cjs](https://github.com/component/builder-es6-module-to-cjs) 65 | - [builder-html-minifier](https://github.com/component/builder-html-minifier) 66 | - [builder-jade](https://github.com/component/builder-jade) 67 | - [builder-regenerator](https://github.com/component/builder-regenerator) 68 | - [builder-myth](https://github.com/mnmly/builder-myth) 69 | 70 | ### Middleware, Servers, and Sites: 71 | 72 | - [component-koa](https://github.com/component/koa.js) - middleware for [koa](https://github.com/koajs/koa). 73 | - [component-middleware](https://github.com/component/middleware.js) - middleware for node, connect, express, etc. 74 | - [component-builder-www](https://github.com/component/builder.www) - experimental build server for a potential Component CDN. 75 | - [component-cdn](https://github.com/component/cdn) - experimental CDN for Component. 76 | - [component.github.io](https://github.com/component/component.github.io) - http://component.io 77 | 78 | ### Documentation: 79 | 80 | - [guide](https://github.com/component/guide) 81 | - [specifications](https://github.com/component/spec) 82 | -------------------------------------------------------------------------------- /component/vs.md: -------------------------------------------------------------------------------- 1 | 2 | Component is one of many frontend solutions. One of the major differences between Component and other solutions is that it is vertically integrated, meaning it does everything from package management to building. Of course, to do so, it is opinionated and is not suitable for every workflow. 3 | 4 | ## What is the long-term goal of Component? 5 | 6 | Component is currently a stopgap for ES6 modules and Web Components. 7 | When all modern browsers start supporting these features, 8 | Component will begin focusing more on semantic versioning and server-side bundling as browsers would be able to handle the rest. 9 | 10 | However, we may still use `component.json` as it allows package managers to accurately describe the package and how to consume it without parsing the files of the package. 11 | 12 | ## When is Component right for me? 13 | 14 | Component's philosophy is the UNIX philosophy of the web - to create a platform for small, reusable components that consist of JS, CSS, HTML, images, fonts, etc. With its well-defined specs, using Component means not worrying about most frontend problems such as package management, publishing components to a registry, or creating a custom build process for every single app. 15 | 16 | ## When is Component wrong for me? 17 | 18 | One of the main philosophies with Component is that each component should generally be independent of each other. If they are not independent, then they should only be dependent as a "dependency". 19 | 20 | Thus, Component may not be suitable if you use a lot of globals, like jQuery, or use frameworks whose plugins could break other plugins, such as Angular JS. 21 | 22 | Since Component is also a package manager, it is not suitable for many frameworks who have their own package management solution, such as [Meteor](http://meteor.com). 23 | 24 | Component, by default, only supports CSS and JS, so using CSS preprocessors whose language is not a superset of CSS may cause issues. 25 | 26 | ## Component vs. npm 27 | 28 | Component uses GitHub as a registry and does not have its own. This is in contrast to `npm`, which has its own user namespace and publishing step. 29 | 30 | Some benefits include: 31 | 32 | - Knowing exactly where code you use is since we use github's `/` namespace 33 | - No downtime, as GitHub's CDN is generally more reliable than `npm` 34 | - No publishing step except for pushing tags to your repository 35 | - No different username than GitHub usernames 36 | - Flat dependencies, which is more suitable for the browser 37 | - Allow multiple versions of the same dependencies 38 | - Faster installations 39 | - No caching of installations, avoiding any `cache clean` issues 40 | - No "unmet dependency" error messages 41 | 42 | ## Component vs. Browserify 43 | 44 | Component is pretty similar to Browserify. One major difference is that Browserify uses `npm` where as Component does not. However, other differences include: 45 | 46 | Browserify resolves dependencies by parsing JS `require()` calls. Component uses `component.json` manifests, which is more verbose. Browserify is easier to use when your app is primarily JS, but Component is easier to use when your app consists of a significant amount of CSS, HTML, images, etc., or if you want to tie JS to its CSS counterparts. 47 | 48 | Browserify aims to make `node` modules work in the browser, many of which are unnecessary. On the other hand, Component aims to create modules specifically for the browser. Browserify is better suited for making `node` modules quickly work in the browser. 49 | 50 | ## Component vs. Bower 51 | 52 | Bower is more similar to `npm` than to Component. Like `npm`, Bower's `bower.json` manifest is inclusive except for everything in the relevant `.ignore` file. Component, on the other hand, is exclusive, downloading files only specified in the `component.json`. 53 | 54 | However, the major difference between Bower and Component is that `component.json`s are more strict and opinionated: all files listed in the `component.json` are __assumed to be mandatory__. On the other hand, files listed in a `bower.json` are generally optional. 55 | 56 | A strict manifest specification allows Component to easily integrate a build process. However, this is impossible with Bower as people publish different types of modules (globals, plugins, AMD, and CommonJS), as well as optional files as shown in this [react-bower issue](https://github.com/reactjs/react-bower/issues/1), making an integrated build process very difficult. 57 | 58 | Component's integrated build system allows you to simply include one script and one stylesheet in your page. There's no juggling ` 38 | 39 | 40 | ``` 41 | 42 | You'll notice that we've linked to __build/build.css__ and __build/build.js__ 43 | files. This is where Component will build files to in the default case. 44 | 45 | ### Create component.json 46 | 47 | Let's create the __component.json__ and set the _name_ property. 48 | 49 | ```json 50 | { 51 | "name": "my-first-component" 52 | } 53 | ``` 54 | 55 | ### Install a remote dependency 56 | 57 | We want to include 58 | [normalize.css](https://github.com/necolas/normalize.css), so let's install 59 | this remote dependency via the command: 60 | `component install necolas/normalize.css`. If you check the __component.json__ 61 | file, you'll notice that component add the dependency automatically. You can also do it the other way: add a dependency, then run `component install`. 62 | 63 | You should see this output on your stdout: 64 | ```bash 65 | github remote: 54 of 60 requests remaining, resetting at Thu Oct 30 2014 00:23:36 GMT+0100 (CET) 66 | github remote: see https://github.com/component/guide/blob/master/changelogs/1.0.0.md#required-authentication for more information. 67 | installed : necolas/normalize.css@3.0.2 in 283ms 68 | install : complete 69 | ``` 70 | 71 | We use `necolas/normalize.css` because that's where the code is hosted 72 | on GitHub.[[1]](#remotes) If you don't specify any version via the command, 73 | component will install the latest version, which is __3.0.2__ in this case. 74 | __^3.0.2__ means that we want to use any version of 75 | __normalize.css__ between __3.0.2__ and below __4.0.0__.[[2]](#semver) 76 | 77 | 78 | ### Create index.css 79 | 80 | Now, let's create a CSS file __index.css__. Let's reset the box model 81 | , to start: 82 | 83 | ```css 84 | * { 85 | box-sizing: border-box; 86 | } 87 | ``` 88 | 89 | ### Create index.js 90 | 91 | Now, let's create a JS file __index.js__ that flashes the `Woo!` every 300 92 | milliseconds in the HTML document. 93 | 94 | ```js 95 | var blink = document.querySelector('.blink'); 96 | 97 | setInterval(function () { 98 | blink.style.visibility = getComputedStyle(blink).visibility === 'hidden' 99 | ? 'visible' 100 | : 'hidden'; 101 | }, 300); 102 | ``` 103 | 104 | ### Add index.js and index.css to component.json 105 | 106 | We need to add our files to the __component.json__, so it will end up looking 107 | like this: 108 | 109 | ```json 110 | { 111 | "name": "my-first-component", 112 | "dependencies": { 113 | "necolas/normalize.css": "^3.0.2" 114 | }, 115 | "scripts": ["index.js"], 116 | "styles": ["index.css"] 117 | } 118 | ``` 119 | 120 | ### `component build` 121 | 122 | Now, we run `component build`. You'll see an output like this: 123 | 124 | ```bash 125 | $ component build 126 | build : resolved in 26ms 127 | build : files in 126ms 128 | build : build/build.js in 135ms - 4kb 129 | build : build/build.css in 130ms - 7kb 130 | ``` 131 | 132 | You'll see __build/build.js__ and __build/build.css__ files as referenced by 133 | __index.html__. 134 | 135 | ### Open index.html 136 | 137 | Run `open index.html` to open the the file in your browser. Now you'll notice 138 | that `Woo!` is flashing: the site is built. 139 | 140 | ## Some observations 141 | 142 | - When you run `component build`, all dependencies (listed in __component.json__) 143 | will be installed automatically, as needed, and included in the build. (This 144 | behavior is different from previous versions of component, which split the 145 | install and build steps.) 146 | 147 | - In __build/build.css__, you'll notice that __normalize.css__ is automatically 148 | included in the build _first_. Component concatenates CSS files in the 149 | following order: remote dependencies first, followed by local dependencies 150 | (i.e. listed in __locals__), followed by css files local to the component 151 | (i.e. listed in __styles__). For more info, see [CSS Ordering][css-ordering]. 152 | 153 | - The __index.js__ will be loaded (required) automatically, so the text starts 154 | flashing immediately when you open the browser. 155 | 156 | - Note that `box-sizing: border-box;` is automatically prefixed with `-webkit` 157 | and `-moz`. Component uses the great [autoprefixer](https://github.com/postcss/autoprefixer) by default to generate vendor prefixes. 158 | 159 | ## Setup Authentication 160 | You might noticed that Component prints a message if you run 161 | `component install`. It looks like this: 162 | ```bash 163 | github remote: 54 of 60 requests remaining, resetting at Thu Oct 30 2014 00:23:36 GMT+0100 (CET) 164 | github remote: see https://github.com/component/guide/blob/master/changelogs/1.0.0.md#required-authentication for more information. 165 | ``` 166 | GitHub provides 60 request per hour for an unauthenticated access. If you 167 | you need more, you need to use authentication. See [changelog](https://github.com/componentjs/guide/blob/master/changelogs/1.0.0.md#required-authentication) for more information. 168 | 169 | ### Configuring GitHub access 170 | 171 | Component 1.0.0 is using GitHub API to access GitHub repos, one simple way to configure your account is by adding global environment variable to your profile (eg: `.bashrc` r `.zshrc`) like this: 172 | 173 | ```bash 174 | export GITHUB_USERNAME= 175 | export GITHUB_PASSWORD= 176 | ``` 177 | 178 | One other secure way is by using GitHub oauth token instead of your password: 179 | 180 | ```bash 181 | export GITHUB_USERNAME= 182 | export GITHUB_PASSWORD=x-oauth-basic 183 | ``` 184 | 185 | You can also use a __.netrc__ file, add the following lines to your `.netrc`](https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html) 186 | 187 | ```bash 188 | machine api.github.com 189 | login 190 | password x-oauth-basic 191 | 192 | machine raw.githubusercontent.com 193 | login 194 | password x-oauth-basic 195 | ``` 196 | 197 | `` is generated in the page , you can validate it via command: 198 | 199 | 200 | ### Configuring bitbucket access 201 | 202 | Component 1.0.0+ supports Bitbucket as a remote as well. The simplest way to support Bitbucket is to add globals to your profile (eg. `.bashrc` or `.zshrc`) like so: 203 | 204 | ```bash 205 | export BITBUCKET_USERNAME= 206 | export BITBUCKET_PASSWORD= 207 | ``` 208 | 209 | Additionally, you can add Bitbucket credentials directly to your [`.netrc`](https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html) file like o: 210 | 211 | ```bash 212 | machine api.bitbucket.org 213 | login 214 | password 215 | ``` 216 | 217 | Currently, Bitbucket does not support generating a personal OAuth access token. The [current documentation on OAuth with BitBucket](https://confluence.atlassian.com/isplay/BITBUCKET/OAuth+on+Bitbucket) only works with app authorization. 218 | 219 | ## Next steps 220 | 221 | If you want to learn different features of component step by 222 | step, you can try out the browse the [c8-experiments repo](https://github.com/timaschew/c8-experiments). 223 | 224 | There are also more [examples](https://github.com/componentjs/guide/blob/master/component/examples.md). 225 | 226 | ----- 227 | **Notes:** 228 | 229 | 230 | [1] Component uses GitHub repos by default, but can be configured to use other 231 | _remotes_ via custom adapters. See [component/remotes.js][remotes] for details. 232 | 233 | 234 | [2] Component uses npm's semantic version string parser ([node-semver][semver]). 235 | 236 | 237 | [css-ordering]: https://github.com/componentjs/guide/blob/master/creating-apps-with-components/css-ordering.md 238 | [remotes]: https://github.com/componentjs/remotes.js 239 | [semver]: https://github.com/npm/node-semver 240 | -------------------------------------------------------------------------------- /changelogs/1.0.0.md: -------------------------------------------------------------------------------- 1 | # Component v1.0.0 2 | 3 | Component has finally received the developer love it needed for a long time! 4 | The goals of this release are: 5 | 6 | - add semantic versioning support 7 | - fix many issues with component in general 8 | - prune `component(1)` of options and features 9 | - make creating components easier 10 | 11 | Please note that `component(1)` is designed for building small, public components, 12 | as well as building apps that do not need a custom build process. 13 | If you need to use plugins for your builds, 14 | you should use the JS API instead. 15 | We don't want to bloat `component(1)` with options, commands, and features. 16 | 17 | For more specific changes, please read the [History.md](https://github.com/component/component/blob/master/History.md). 18 | 19 | ## What's New 20 | 21 | ### Required Authentication 22 | 23 | Actually you don't need an authentication for GitHub, but then you only get 60 API request per hour. With authenticated requests you get 5.000 per hour. 24 | 25 | See [GitHub API Documentation](https://developer.github.com/v3/#rate-limiting) for more information. 26 | 27 | Component tell you when your limit is running short via stdout. You can see an example at the [remotes.js travis build](https://travis-ci.org/componentjs/remotes.js/jobs/36446838#L104). You get these information: 28 | 29 | - your rate limit 30 | - your remaining requests 31 | - reset date, when you get more requests again 32 | 33 | To authenticate, simply either use a [.netrc](https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html) file 34 | or use the appropriate environmental variables for each end point. 35 | These environmental variables are currently: 36 | 37 | - `GITHUB_USERNAME` 38 | - `GITHUB_PASSWORD` 39 | - `BITBUCKET_USERNAME` 40 | - `BITBUCKET_PASSWORD` 41 | 42 | Instead of providing your password as plaintext you might be interested in using a token. You can create your token on this site [personal access tokens](https://github.com/settings/applications#personal-access-tokens). 43 | 44 | .netrc example (location: `~/.netrc`): 45 | 46 | ``` 47 | machine api.github.com 48 | login 49 | password x-oauth-basic 50 | ``` 51 | 52 | ### Semantic Versioning 53 | 54 | For a while, Component users were plagued by a lack of semantic versioning support. 55 | But fear no longer! Component now supports semver. 56 | This also means that Component supports multiple versions of a dependency in a single build __and__ app. 57 | You'll notice that components are now installed as `//` instead of `-`. 58 | 59 | Please use semver ranges in your public components. 60 | You'll notice when you `component install /`, 61 | components will now be installed with a `^` if `> v1.0.0` and `~` otherwise. 62 | Since we're dealing with frontend development, we want as few duplicates as possible. 63 | 64 | But please, stop using `*`! 65 | 66 | ### Pinning and Updating 67 | 68 | Although semantic versioning is great, you still want to pin your app's dependencies to specific versions. 69 | Otherwise, a dependency might break your app and hunting the cause might be nontrivial. 70 | So Component has added a few commands to make pinning dependencies and updating them easier. 71 | 72 | - `component pin` - pin all your dependencies that use semver ranges to a single version. 73 | - `component outdated` - check whether any of your pinned dependencies are outdated. 74 | - `component update` - update all your pinned dependencies to the latest version. 75 | - `component duplicates` - list any duplicates of dependencies and their dependents 76 | 77 | Note that these commands only update the `component.json` files. 78 | To actually install these new versions, 79 | run `component install` again. 80 | 81 | ### ~~Registry~~ Crawler 82 | 83 | Most package managers have a registry, but we've found that these registries are an extra source of pain. 84 | Instead, Component uses GitHub as a registry! 85 | For a while, we used a [wiki](https://github.com/component/component/wiki/Components) to keep track of components, 86 | but this was a pain in the ass to update and maintain. 87 | 88 | Now, we have a dedicated crawler that simply crawls a github user or organization for components! 89 | Instead of a publish step, all you have to do is `component crawl `, and __all__ of your components will essentially be "published". 90 | Users can now search for your component using `component search` or at http://component.github.io 91 | 92 | ### ES6 Module Support 93 | 94 | Component v1 now supports ES6 modules by default. 95 | Simply write an ES6 module with node-like module references, and your app should still work. 96 | 97 | Note that CommonJS and ES6 modules are not completely compatible, ES6 modules aren't standardized yet, and ES6 to CommonJS transpilers are thus not yet stable. 98 | Thus, you may run into issues. 99 | Please let us know if you find any issues! 100 | The relevant repository is: http://github.com/component/builder-es6-module-to-cjs. 101 | 102 | ### Smarter `require()`s 103 | 104 | Not all the maintainers of the [component](https://github.com/component) organization use Component - many use `npm` and `browserify`. 105 | However, this has been a pain as components are generally named with `npm`'s namespace in mind. 106 | 107 | The solution now is to use `require(-)` in your components, then publish the component to `npm` as `-`. 108 | No more aliasing hackery will be required on the `browserify` and `node` side. 109 | 110 | ### Watcher 111 | 112 | Component now has a `component build --watch` option, allowing incremental builds. It uses [sane](http://github.com/amasad/sane) under the hood, which seems to be one of the best JS watcher libraries currently published. 113 | 114 | ### Linking 115 | 116 | You may now link local components as version dependencies in your app using the `component link ../path/to/folder` command. 117 | 118 | ### Glob Support 119 | 120 | Many people complained about having to list every single file in a `component.json` manually. 121 | Now you can simply do `"js": ["**/*.js"]`! 122 | Keep in mind that this will slow down your build process, 123 | so only use globs when necessary. 124 | 125 | ### Easier Local Components 126 | 127 | Creating local components is now easier! For one, you can just use globs instead of listing every single file. 128 | But most of all, you don't have to name each local's `component.json`. Component will just use its containing folder's name. 129 | 130 | ### Development Build 131 | 132 | Component supports now __locals__, __scripts__ and __styles__ for the test environment via `component build --dev`, 133 | see [example](https://github.com/timaschew/c8-experiments/blob/e7a/lib/my-component/component.json#L17-L34). If you use mocha as test runner you can setup your `test.html` like this: 134 | 135 | ```html 136 | 137 | 138 |
139 | 144 | ``` 145 | 146 | ## What's Removed 147 | 148 | ### Custom Remotes 149 | 150 | For now, `component(1)` only supports GitHub and Bitbucket as remotes. 151 | This is primarily because of semantic versioning support - we have to create an adapter for every remote. 152 | If you need to use a remote other than GitHub or Bitbucket, 153 | you should stick to `v0.x` for now. 154 | 155 | Feel free to add more [remotes](https://github.com/component/remotes.js)! 156 | 157 | ### Commands 158 | 159 | Some commands have been removed as they were deemed unnecessary. 160 | These commands are: 161 | 162 | - `component create` - has moved to https://github.com/component/create.js. It may be re-added at a later date after improvements are made. 163 | - `component convert` - no longer necessary as Component now supports JSON and HTML strings. 164 | - `component wiki` - the official "registry" has moved from the wiki to the crawler as stated above 165 | 166 | `component info` and `component changes` were used to get info about a specific component. However, there were many issues with this, such as some components not having a changelog and others having a changelog name with different casing. Thus, it has been replaced with `component open`, which just opens the component's GitHub page. This is not bound to fail, and is overall more user-friendly. 167 | 168 | ### component install --force 169 | 170 | Force was terribly broken, and was mainly required due to the old installer's inability to handle bad installs. 171 | The new installer now handles failed installations correctly (only successful installations are actually saved). 172 | 173 | If you need to remove or uninstall a component, you can run `rm -rf components` or `rm -rf components//`. 174 | A CLI utility to do those two simple commands wouldn't be very useful. 175 | 176 | ### component build --use 177 | 178 | Support for using plugins from `component(1)` has been removed. 179 | If you need to use a builder plugin, 180 | you should use the JS API instead. 181 | 182 | ## What's Changed 183 | 184 | ### component.json 185 | 186 | The `component.json` [specifications](https://github.com/component/spec/blob/master/component.json/specifications.md) have changed over time. 187 | `component validate` will warn you of any changes. Generally, these changes are backwards compatible in that Component `1.0.0` can still handle them. 188 | 189 | - `.templates` has been added, removing the necessity of `component convert`. 190 | - `.local` has been renamed to `.locals` as it is an array. 191 | - `.repo` has been renamed to `.repository` . 192 | - `.development` is now a hash of development-only fields. In other words, its usage has changed to `.development.dependencies`. 193 | - `.remotes` now handles an array of strings which refer to an remote implementation: `'github'` and `'bitbucket'`, see [spec](https://github.com/componentjs/spec/blob/master/component.json/specifications.md#remotes) 194 | 195 | ### Breaking Changes 196 | 197 | - Since Component supports semantic versioning, dependencies with `*` fetch the latest published tag now. The master branch will only be used if there are no tags available. 198 | - The __require__ implementation has changed. In versions < 1.0.0, you could do dynamic require: `require(base + 'someFile')`. This is not possible anymore, because component need to parse all `require()` calls at build time and resolve the paths. Only a string identifier is allowed in the require path. 199 | - The canonical require path has changed. If you want to require locals which are not the first (boot) component, you need the canonical path. If you have main component like [this](https://github.com/componentjs/boilerplate-express/blob/master/component.json), then the canonical path is `./client/boot`. Non-[main files](https://github.com/componentjs/spec/blob/master/component.json/specifications.md#main) of a local need to be required with the file name __and__ the file extension, for instance: `./client/boot/helper.js`. 200 | A use case for canonical paths is to require test files for the development environment (`component build --dev`), [see example](https://github.com/timaschew/c8-experiments/blob/e7a/test/index.html#L18). 201 | 202 | ### Massive Internal Changes 203 | 204 | The internals of `component(1)` have also changed drastically. 205 | Be sure to understand the internal modules if you wish to use the more powerful JS API. Here's a [list of all official Component respositories](../component/repositories.md). 206 | -------------------------------------------------------------------------------- /component/faq.md: -------------------------------------------------------------------------------- 1 | 2 | > Please note that this FAQ is a little out of date and was written before 1.0.0. 3 | 4 | ## Why components? 5 | 6 | Client-side development currently suffers from a lack of structure, more importantly this lack of structure and fundamental sharing of assets makes it difficult to abstract libraries into smaller subsets. Normally you would think twice about separating your library into several parts, because telling end-users to install several pieces is tedious, error-prone, and frankly annoying. Component makes this extremely easy, and we may all benefit from creating smaller lego-blocks for the web. 7 | 8 | ## What is a component? 9 | 10 | As mentioned in my original [blog post](http://tjholowaychuk.tumblr.com/post/27984551477/components) components are packages containing any combination of assets. For example a component may be javascript and css, fonts and images, only css, or only javascript. Components may also have server portions as well, however for (most) public components this is not recommended, as server components written in different languages are obviously difficult to share among communities. Components are _not_ related to node in any way, however the implementation of the `component(1)` executable that I have created was written with node. 11 | 12 | ## Why component.json and why not use npm? 13 | 14 | While this is not set in stone, going with component.json instead of package.json removes the ambiguity of which packages may or not actually support "components". package.json has been twisted and changed to suit specific needs of npm as well as other javascript environments, though it could be "fixed" we see the clear separation as a clean break, treating components as first class citizens, not an after-thought. 15 | 16 | Due to npm's "global" registry namespace even the name field of component.json and package.json may differ, if your package supports both environments this simply does not work because npm has exhausted many common names, and dependencies are defined in a different manner, thus rendering them incompatible. 17 | 18 | For projects that do happen to support both component and node.js this may appear to be an annoyance, however a very small one. Adding fallback mechanisms to component for package.json support only complicates implementations, documentation, and produces additional unnecessary confusion. Component is designed as a fresh take on how things could be, not what they were. 19 | 20 | Another issue with using npm is that packages are ambiguous between environments. Attempts have been made to allow _any_ npm module to work in the browser, regardless of it being designed as such, making discovery and compatibility more difficult. 21 | 22 | We also utilize many JSON keys that have different meanings in package.json, and others which are not guaranteed to be safe in the long-term. 23 | 24 | Lastly npm conveniences only node users. With the component spec developers may use the component(1) written with node, or implement their own to match the spec. Asking "why not use npm?" is like asking "why not use gem?", or any other package manager. Components are a concept not an implementation. 25 | 26 | The component.json requirements are detailed in the [[Spec]] 27 | 28 | ## How can I use components on node? 29 | 30 | You can have a look at [component-as-module](https://github.com/eldargab/component-as-module). 31 | 32 | ## Why Github style namespacing? 33 | 34 | Some may view this as a "bad" feature, however it comes with a few nice benefits. The 35 | first being that you automatically know where docs can be found because you know where 36 | the repository lives! 37 | 38 | Another benefit is that there is no name squatting, anyone can use whatever name they like. 39 | For example `component/dialog`, `visionmedia/dialog`, and `tootallnate/dialog` all use the 40 | name "dialog", however you could use all three as dependencies in various components within 41 | your application, and still `require('dialog')`. 42 | 43 | This dependency on Github is only implied, but not specifying a _full_ url in component.json 44 | files you may use a simple [file server](https://github.com/component/server) to either localize 45 | modifications to components on Github, or to serve private components for your organization. 46 | 47 | ## Why commonjs instead of AMD? 48 | 49 | Arguably both AMD and build steps are codesmell, however we're aiming to make the development experience a better one by helping to write cleaner modules. How these modules get loaded is purely an implementation detail. With the help of explicit dependencies listed in component.json there's nothing stopping components from being loaded async as needed, or choosing to do a single, or several file build, that choice is yours to make for your application's needs. Many AMD applications compile to single files for production anyway, as 300+ xhrs (at least today) would not be a great idea. AMD vs CJS is mostly just a subjective style debate. 50 | 51 | ## Why explicitly list all assets in component.json? 52 | 53 | Some expect component(1) to auto-discover scripts via parsing `require()`s, personally I find this an unnecessary hack, for several reasons. The first being that if your component has enough scripts that it's inconvenient to list a few in an array, then that's a sure sign your component is too large. Secondly this adds additional needless complication to implementations of component, and lastly the explicit listing of assets is what makes `component install` so much faster than similar tools, we can download binaries directly in parallel from the remote instead of git clones, or fetching and unpacking tarballs. 54 | 55 | ## Do I have to manually build all the time? 56 | 57 | No, the `component build` command is one method of performing a build, however you may use a builder within your application (builder.js for example), to re-build on request. The `component build` command is great for development of individual components because it's already available to you and requires no setup. I recommend using a "watcher" (https://github.com/visionmedia/watch) and backgrounding this while you work on a component, then it's as if there was no build step at all, you'll just be able to work on the component's assets freely. For example `$ watch make &`, then `fg` to bring that job back as the foreground job in your shell. 58 | 59 | ## Can I use component as a build tool for my larger framework? 60 | 61 | Yes! Large frameworks like Angular, Ember, or even smaller ones like Backbone may still benefit from utilizing components. By separating these behemoths into smaller pieces not only does it decrease coupling for the authors, you get all of the development environment benefits that components provide, while still being able to produce a "stand-alone" build for distribution to users via `component build --standalone`. Additionally this allows users who _do_ use component to access your framework through it, as well as all the subcomponents, it's a win-win for both parties. 62 | 63 | ## Will component work with Rails, Django, [your framework here]? 64 | 65 | Yes! The spec was designed in such a way to maximize simplicity so that 66 | other communities could write similar tool-chains in their own native language. Nothing about component is coupled with node.js, however the current set of "official" tools is written with node. Eventually we may ship binaries to make this even easier. 67 | 68 | ## How do I use local private dependencies? 69 | 70 | To use private components, add a `"local"` key to `component.json`, for example: `"local": ["foo", "bar"]`. Local dependencies will not be installed from a remote location, but `component(1)` will traverse them and install any dependencies these components may have. 71 | 72 | If you want to use different directories for components, for example `./components` for public components and `./lib` for private components, add a `"paths"` key to your `component.json`, as follows: `"paths": ["components", "lib"]`. `component(1)` will then search both `./components` and `./lib` for components. 73 | 74 | 75 | ## How do I use private Github repositories? 76 | 77 | You just need to use authentication via environmental variables or __.netrc__ file. 78 | 79 | Alternatively you may serve private components without Github using any web server that uses the same urls as Github. See Julian Gruber's [contre](https://github.com/godmodelabs/contre) as one example of this with git integration, or the [component/server](https://github.com/component/server) example which serves from components disk. 80 | 81 | ## How should I structure my application? 82 | 83 | This is a heated debate, with no real answer. The sample [Todo list](https://github.com/component/todo) application has several branches, each implementing a different application structure to demonstrate various ways to approach the task. Some prefer structuring their application linearly by "resource", as in a single flat-listed directory containing all client / server components in one. Others prefer traditional Rails-style MVC directory structure focusing on domain-specific tasks, and splitting associated resource files into directories such as "models", "controllers" and "views". There are pros and cons of each approach, it's your call. 84 | 85 | ## Can I use components without component(1)? 86 | 87 | Any component can be built to produce a "standalone" version. This build wraps all the dependencies in a function and exposes only a single global variable that you specify, allowing _any_ component to work in _any_ application. To do this simply execute the following in a component directory: 88 | 89 | $ component build --standalone myGlobalVariable 90 | 91 | ## Where can I find branding documents for component? 92 | 93 | All logos and other assets will be uploaded to [https://github.com/component/component/downloads](https://github.com/component/component/downloads). 94 | 95 | ## What about "Web Components"? 96 | 97 | The "Web Components" spec is an umbrella term for various client-side technologies that will help developers create reusable code. This includes Shadow DOM, scoped styles, decorators and so on, many of which are very useful features, however do not "solve" other problems such as packaging, component discovery, installation, builds etcetera. 98 | 99 | We view the future of web components to be complimentary to our effort with component(1), our components serve as a solid abstraction that will work seamlessly with or without web components. For example web components require a single `.html` file for the browser to fetch, which we may easily compile with our existing system, without developer modifications, making component(1) a future-proof solution which remains working for legacy systems. 100 | 101 | In short web components themselves won't really affect how component(1) developers build components at all, you'll just have additional browser features available to you for creating custom tags and so on. 102 | 103 | ## What are the benefits of creating an application out of private components? 104 | 105 | Modern applications are often developed in a non-modular fashion, for example CSS often lives in a directory such as `./styles`, views in `./views`, models in `./models` and so on. While this is certainly not a poor way to develop an application, there are several benefits and gotchas when creating an application solely from well-defined modules. 106 | 107 | If your application shares code between one or more other applications using modules makes it extremely easy to share between the two. If you suddenly decide another application could really use this private module you can simply copy/paste, link, or create a private repo out of what already exists in your codebase. Removing unused code is also another nice benefit since all dependencies, styles, scripts, etc are self-contained within the module you can simply delete the directory. Normally this can be a painstaking process as it's unclear what utilities, styles, images and scripts relate to the module. 108 | 109 | One obvious downside of this technique is the bookkeeping overhead of maintaing dependencies within each module instead of at the application-level. 110 | --------------------------------------------------------------------------------