-
Notifications
You must be signed in to change notification settings - Fork 304
F.A.Q
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.
As mentioned in my original blog post 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.
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. component.json requirements are detailed in the Spec. 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, simply because npm has exhausted many common names.
Some may view this as a "bad" feature, however it comes with a few nice benefits. The first being that you automatically know where docs can be found because you know where the repository lives!
Another benefit is that there is no name squatting, anyone can use whatever name they like.
For example component/dialog
, visionmedia/dialog
, and tootallnate/dialog
all use the
name "dialog", however you could use all three as dependencies in various components within
your application, and still require('dialog')
.
This dependency on Github is only implied, but not specifying a full url in component.json files you may use a simple file server to either localize modifications to components on Github, or to serve private components for your organization.
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 stoping 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.
The upcoming web components spec wants you to write styles, templates, and scripts in a single .html file that can be loaded by the browser. This is a great step towards reusable components, and ridding the world of framework-specific implementations, however at the end of the day you still want clean code. When web components become standard I would propose that we write our components in stand-alone .css, .js, and .html files like we do today, and simply compile them to .html that a browser can consume.
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.
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.
The first reason being the same as the "component.json" answer above, secondly that npm has nothing to do with client-side assets, nor does node, they should not be coupled. npm conveniences only node users. With the component spec users may use the component(1) I've created (using node), or implement their own to match the spec.
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.
Yes! The spec was designed in such a way to maximize simplicity so that 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.
Add a "locals"
of component names, these will not be installed from any of the remote(s)—e.g add to your app's component.json
"local": ["foo", "bar"]
—however component(1)
will traverse them and install their dependencies. Often ./components
will be .gitignore
d, and local deps may be kept in a directory such as ./lib
or similar. To facilitate this we have the COMPONENT_PATH environment variable which acts much like the PATH you're all used to. By setting this environment variable to lib
in this case it will allow component to install their deps and include them in the builds.
Adding a remote
of raw.github.com
with basic auth credentials will allow you to utilize private components like so:
{
"remotes" : [
"https://user:[email protected]"
]
}
Alternatively you may serve private components without Github using any web server that uses the same urls as Github. See Julian Gruber's contre as one example of this with git integration, or the component/server example which serves from components disk.
This is a heated debate, with no real answer. The sample Todo list 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.
Any component can 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:
$ component build --standalone myGlobalVariable
All logos and other assets will be uploaded to https://github.com/component/component/downloads.