Build a Web app with component(1)17 Feb 2014
All in one place
Currently, the common architecture is to split files into different directories.
For instance, this is how the files tree may look like for a menu:
With component(1), we can regroup the logic and UI that define the menu component.
We find all information about this component in one place. We should also add tests to be sure the component is bug free, before integrating it to the rest of the application.
A readme file or demo page could help our colleagues, other developers or the future "me" to understand easily what the component does and how it works. Nothing really new, but in my opinion it simplifies the process a lot.
There are a few things to know about component(1) registry system. It is based on GitHub style namespacing username/repository. It avoids name conflict, therefore you can choose the one you desire.
To share a component with the community, you need to push it on GitHub, then add the repository link into the wiki page to register it. The component will be accessible on component.io or via the command
However you don't need to register a component to be able to install it.
To install component(1), Node.js is required.
component(1) cli commands
Component(1) comes with multiple commands. You can printout the list with
Here is those I use often:
search [query]: search registered component.
wiki: open the components list page. Another way to find components.
create [dir]: create a component skeleton.
install [name ...]: install one or more components.
build: build the component. I will talk about it later.
Create a component
In this example we will create a progress bar component.
First of all, we have to create a
component.json file in which we add all the information about the component.
We can also use the command
component create progress-bar to create the component's structure.
Build the component
Component(1) module definition is based on CommonJS spec, like Node.js. You can find more information about CommonJS module in this article.
We need to define the logic and the UI of the component. Let's create
template.html as we specified in
To be able to test the component we need to build it:
--dev option adds source map which is really helpful for debugging. You can find more options with
component build --help.
While developing a small component like this, I use rewatch to execute the build command every time I save a file. There is no point in using Grunt or Gulp in that case.
Finally, we add a demo page to see how it looks.
Test your component
There are different possibilities to test a component: Mocha, Zuul, component-test, ... And certainly others I don't know yet.
I currently use component-test. It is simple to use and doesn't need configuration. You can run the test in the browser, PhantomJS or Sauce Labs. If you want more information, the readme is well documented.
Whatever solution you prefer to use, don't forget to test your code.
We can now push the code to GitHub and add the link to Component's wiki.
Don't forget to add a tag (
git tag) for each version you release. Otherwise you won't be able to specify a version number when you use it as a dependency. Which is really dangerous, if one day you decide to change the component's API, it will break applications that use it. If you are lazy, you can still use mversion.
Structuring an application
Let's pretend we want to develop an application which contains:
- Two pages: home and about.
- A script to load images.
The file at the root of the project is the main
component.json of the application. This is where we will run the command to build the application.
paths property is used by the builder to know where it has to look at to find
Here we just specify
boot, the entry point of the application, located in
Each components define their own dependencies, local or published, therefore we don't need to add more information in this
boot component will be the first script executed in the application.
It manages routing (
visionmedia/page.js) and transitions between each pages. It also defines the base of the interface, using normalize.css,
We add the pages components, home and about, as local dependencies.
To use a static assets, like the background image, you just need to use relative file path.
component build symlinks those files to the build folder and replace the
url() values (except if you specify an absolute path).
The pages use the local component to load images and
emitter to communicate with
I pushed an example on GitHub to show how an application could be organized. I also used Sass for the demo.
Sometimes you may wonder if you need to move a component to its own repository. Personally, when I'm working on a project, I only creates local components. When the project ends, I extract components that can be useful for a new project.
At North Kingdom we started to do that after the launch of The Hobbit project. We share our components in nk-components.
When it comes to build larger applications, you may want to use CSS preprocessor or template engines.
--use option, where you define the list of plugins it has to execute.
If you don't want to use component-build(1) but prefer tasks runner like Grunt or Gulp, I suggest you to use grunt-component-build or gulp-component. It is possible to create your own build script using builder.js.
Building the application
To build the application you need to be at the root of the project (where the main
component.json is located) and run:
component install: installs the dependencies defined by local components.
component build: build the files that will be included into the
The final step is to create the
index.html that will be served to the user.
Don't forget to require
boot, otherwise the application will never start.
I really like the way we organize applications with component(1), where each component is developed and lives separately in the project.
At North Kingdom, we don't use a specific framework like Backbone or Angular. Each project has different constraints, some need to be connected to a database, some need to handle deep links... component(1) lets us to be flexible and just use what we really need. We find a lot of good resources published by the community and the number of shared components is still growing.
Component(1) has some drawback like the file size. Aliases, at the bottom of
build.js, could take >10% of the file size. Which is a lot compared to other solution like browserify.
Also, it may seem tedious to have to reference each of the dependencies and modules for each of the components. This is a design choice, but this could be simplified with a generator like Yeoman.
I see it as a preview of the future of Web development. Web Components will be available in modern browsers in a few years with even more powerful features. The team behind component(1) plans to support Web Components and this is a great news.
In another post, I plan to talk about my workflow and tools I use to simplify the creation of components.